mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-09-10 12:03:18 +02:00
chat-view: simplify chat details panels and save split states
- Saves (session only) the open state of the swarm details panel - Saves the details index, and falls back when not available Gitlab: #902 Change-Id: I7ad0c53007dac95f4b1984fc1fcf0094ae59a755
This commit is contained in:
parent
8832f40b19
commit
4d2e31a5f3
10 changed files with 229 additions and 281 deletions
|
@ -577,8 +577,8 @@ Item {
|
||||||
|
|
||||||
property real mainViewMargin: 30
|
property real mainViewMargin: 30
|
||||||
|
|
||||||
// Details page
|
// Extras panel
|
||||||
property real detailsPageMinWidth: 300
|
property real extrasPanelMinWidth: 300
|
||||||
property int aboutBtnSize: 24
|
property int aboutBtnSize: 24
|
||||||
|
|
||||||
// Messages point size
|
// Messages point size
|
||||||
|
|
|
@ -307,12 +307,6 @@ CurrentConversation::connectModel()
|
||||||
Qt::UniqueConnection);
|
Qt::UniqueConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
CurrentConversation::showSwarmDetails()
|
|
||||||
{
|
|
||||||
Q_EMIT showDetails();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CurrentConversation::updateErrors(const QString& convId)
|
CurrentConversation::updateErrors(const QString& convId)
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,7 +61,6 @@ public:
|
||||||
explicit CurrentConversation(LRCInstance* lrcInstance, QObject* parent = nullptr);
|
explicit CurrentConversation(LRCInstance* lrcInstance, QObject* parent = nullptr);
|
||||||
~CurrentConversation() = default;
|
~CurrentConversation() = default;
|
||||||
Q_INVOKABLE void scrollToMsg(const QString& msgId);
|
Q_INVOKABLE void scrollToMsg(const QString& msgId);
|
||||||
Q_INVOKABLE void showSwarmDetails();
|
|
||||||
Q_INVOKABLE void setPreference(const QString& key, const QString& value);
|
Q_INVOKABLE void setPreference(const QString& key, const QString& value);
|
||||||
Q_INVOKABLE QString getPreference(const QString& key) const;
|
Q_INVOKABLE QString getPreference(const QString& key) const;
|
||||||
Q_INVOKABLE MapStringString getPreferences() const;
|
Q_INVOKABLE MapStringString getPreferences() const;
|
||||||
|
@ -71,7 +70,7 @@ public:
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void reloadInteractions();
|
void reloadInteractions();
|
||||||
void scrollTo(const QString& msgId);
|
void scrollTo(const QString& msgId);
|
||||||
void showDetails();
|
void showSwarmDetails();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void updateData();
|
void updateData();
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2022 Savoir-faire Linux Inc.
|
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
|
||||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
|
||||||
* Author: Trevor Tabah <trevor.tabah@savoirfairelinux.com>
|
|
||||||
* Author: Andreas Traczyk <andreas.traczyk@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
|
||||||
|
@ -21,11 +18,11 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import Qt5Compat.GraphicalEffects
|
|
||||||
|
|
||||||
import net.jami.Models 1.1
|
import net.jami.Models 1.1
|
||||||
import net.jami.Adapters 1.1
|
import net.jami.Adapters 1.1
|
||||||
import net.jami.Constants 1.1
|
import net.jami.Constants 1.1
|
||||||
|
import net.jami.Enums 1.1
|
||||||
|
|
||||||
import "../../commoncomponents"
|
import "../../commoncomponents"
|
||||||
import "../js/pluginhandlerpickercreation.js" as PluginHandlerPickerCreation
|
import "../js/pluginhandlerpickercreation.js" as PluginHandlerPickerCreation
|
||||||
|
@ -33,13 +30,17 @@ import "../js/pluginhandlerpickercreation.js" as PluginHandlerPickerCreation
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
// An enum to make the details panels more readable.
|
||||||
|
enum Panel {
|
||||||
|
SwarmDetailsPanel,
|
||||||
|
MessagesResearchPanel,
|
||||||
|
AddMemberPanel
|
||||||
|
}
|
||||||
|
|
||||||
color: JamiTheme.chatviewBgColor
|
color: JamiTheme.chatviewBgColor
|
||||||
|
|
||||||
property var mapPositions: PositionManager.mapStatus
|
property var mapPositions: PositionManager.mapStatus
|
||||||
|
|
||||||
property int lastContentsSplitSize: JamiTheme.detailsPageMinWidth
|
|
||||||
property int lastDetailsSplitSize: JamiTheme.detailsPageMinWidth
|
|
||||||
property int previousWidth: width
|
|
||||||
required property bool inCallView
|
required property bool inCallView
|
||||||
|
|
||||||
signal dismiss
|
signal dismiss
|
||||||
|
@ -51,10 +52,6 @@ Rectangle {
|
||||||
|
|
||||||
function resetPanels() {
|
function resetPanels() {
|
||||||
chatViewHeader.showSearch = true
|
chatViewHeader.showSearch = true
|
||||||
swarmDetailsPanel.visible = false
|
|
||||||
addMemberPanel.visible = false
|
|
||||||
chatContents.visible = true
|
|
||||||
messagesResearchPanel.visible = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function instanceMapObject() {
|
function instanceMapObject() {
|
||||||
|
@ -79,21 +76,24 @@ Rectangle {
|
||||||
Connections {
|
Connections {
|
||||||
target: CurrentConversation
|
target: CurrentConversation
|
||||||
function onIdChanged() {
|
function onIdChanged() {
|
||||||
|
extrasPanel.restoreState()
|
||||||
MessagesAdapter.loadMoreMessages()
|
MessagesAdapter.loadMoreMessages()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: extrasPanel.restoreState()
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (visible){
|
if (visible) {
|
||||||
chatViewHeader.showSearch = !root.parent.showDetails
|
chatViewSplitView.resolvePanes(true)
|
||||||
addMemberPanel.visible = false
|
|
||||||
messagesResearchPanel.visible = false
|
if (root.parent.objectName === "CallViewChatViewContainer") {
|
||||||
if (root.parent.showDetails) {
|
chatViewHeader.showSearch = !root.parent.showDetails
|
||||||
chatContents.visible = false
|
if (root.parent.showDetails) {
|
||||||
swarmDetailsPanel.visible = true
|
extrasPanel.switchToPanel(ChatView.SwarmDetailsPanel)
|
||||||
} else {
|
} else {
|
||||||
chatContents.visible = true
|
extrasPanel.closePanel()
|
||||||
swarmDetailsPanel.visible = false
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,60 +118,9 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
onBackClicked: root.dismiss()
|
onBackClicked: root.dismiss()
|
||||||
|
onShowDetailsClicked: extrasPanel.switchToPanel(ChatView.SwarmDetailsPanel)
|
||||||
signal panelsVisibilityChange()
|
onSearchClicked: extrasPanel.switchToPanel(ChatView.MessagesResearchPanel)
|
||||||
|
onAddToConversationClicked: extrasPanel.switchToPanel(ChatView.AddMemberPanel)
|
||||||
onPanelsVisibilityChange: {
|
|
||||||
if (!swarmDetailsPanel.visible && !messagesResearchPanel.visible) {
|
|
||||||
chatContents.visible = true
|
|
||||||
} else {
|
|
||||||
if (chatViewHeader.width - JamiTheme.detailsPageMinWidth < JamiTheme.mainViewPaneMinWidth)
|
|
||||||
chatContents.visible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onShowDetailsClicked: {
|
|
||||||
addMemberPanel.visible = false
|
|
||||||
messagesResearchPanel.visible = false
|
|
||||||
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: {
|
|
||||||
if (inCallView)
|
|
||||||
return
|
|
||||||
const isExpanding = previousWidth < width
|
|
||||||
|
|
||||||
if (!swarmDetailsPanel.visible && !addMemberPanel.visible && !messagesResearchPanel.visible)
|
|
||||||
return
|
|
||||||
if (chatViewHeader.width < JamiTheme.detailsPageMinWidth + JamiTheme.mainViewPaneMinWidth
|
|
||||||
&& !isExpanding && chatContents.visible) {
|
|
||||||
lastContentsSplitSize = chatContents.width
|
|
||||||
lastDetailsSplitSize = Math.min(JamiTheme.detailsPageMinWidth, (swarmDetailsPanel.visible
|
|
||||||
? swarmDetailsPanel.width
|
|
||||||
: addMemberPanel.visible
|
|
||||||
? addMemberPanel.width
|
|
||||||
: messagesResearchPanel.width))
|
|
||||||
chatContents.visible = false
|
|
||||||
} else if (chatViewHeader.width >= JamiTheme.mainViewPaneMinWidth + lastDetailsSplitSize
|
|
||||||
&& isExpanding && !layoutManager.isFullScreen && !chatContents.visible) {
|
|
||||||
chatContents.visible = true
|
|
||||||
}
|
|
||||||
previousWidth = width
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: CurrentConversation
|
target: CurrentConversation
|
||||||
|
@ -183,28 +132,6 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: CurrentConversationMembers
|
|
||||||
|
|
||||||
function onCountChanged() {
|
|
||||||
if (CurrentConversationMembers.count >= 8 && addMemberPanel.visible) {
|
|
||||||
swarmDetailsPanel.visible = false
|
|
||||||
addMemberPanel.visible = !addMemberPanel.visible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onAddToConversationClicked: {
|
|
||||||
swarmDetailsPanel.visible = false
|
|
||||||
if (addMemberPanel.visible) {
|
|
||||||
chatContents.visible = true
|
|
||||||
} else {
|
|
||||||
if (chatViewHeader.width - JamiTheme.detailsPageMinWidth < JamiTheme.mainViewPaneMinWidth)
|
|
||||||
chatContents.visible = false
|
|
||||||
}
|
|
||||||
addMemberPanel.visible = !addMemberPanel.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
onPluginSelector: {
|
onPluginSelector: {
|
||||||
// Create plugin handler picker - PLUGINS
|
// Create plugin handler picker - PLUGINS
|
||||||
PluginHandlerPickerCreation.createPluginHandlerPickerObjects(
|
PluginHandlerPickerCreation.createPluginHandlerPickerObjects(
|
||||||
|
@ -270,20 +197,50 @@ Rectangle {
|
||||||
visible: CurrentConversation.activeCalls.length > 0 && !root.inCallView
|
visible: CurrentConversation.activeCalls.length > 0 && !root.inCallView
|
||||||
}
|
}
|
||||||
|
|
||||||
SplitView {
|
JamiSplitView {
|
||||||
id: chatViewMainRow
|
id: chatViewSplitView
|
||||||
|
objectName: "ChatViewSplitView"
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
||||||
handle: Rectangle {
|
splitViewStateKey: "Chat"
|
||||||
implicitWidth: JamiTheme.splitViewHandlePreferredWidth
|
|
||||||
implicitHeight: root.height
|
property real previousDetailsWidth: extrasPanel.width
|
||||||
color: JamiTheme.primaryBackgroundColor
|
property real previousWidth: width
|
||||||
Rectangle {
|
onWidthChanged: resolvePanes()
|
||||||
implicitWidth: 1
|
// This function governs the visibility of the chatContents and tracks the
|
||||||
implicitHeight: root.height
|
// the width of the SplitView and the details panel. This function should be
|
||||||
color: JamiTheme.tabbarBorderColor
|
// called when the width of the SplitView changes, when the SplitView is shown,
|
||||||
|
// and when the details panel is shown. When called with force=true, it is being
|
||||||
|
// called from a visibleChanged event, and we should not update the previous widths.
|
||||||
|
function resolvePanes(force=false) {
|
||||||
|
// If the details panel is not visible, then show the chatContents.
|
||||||
|
if (!extrasPanel.visible) {
|
||||||
|
chatContents.visible = true
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Next we compute whether the SplitView is expanding or shrinking.
|
||||||
|
const isExpanding = width > previousWidth
|
||||||
|
|
||||||
|
// If the SplitView is not wide enough to show both the chatContents
|
||||||
|
// and the details panel, then hide the chatContents.
|
||||||
|
if (width < JamiTheme.mainViewPaneMinWidth + extrasPanel.width
|
||||||
|
&& (!isExpanding || force) && chatContents.visible) {
|
||||||
|
if (!force) previousDetailsWidth = extrasPanel.width
|
||||||
|
chatContents.visible = false
|
||||||
|
} else if (width >= JamiTheme.mainViewPaneMinWidth + previousDetailsWidth
|
||||||
|
&& (isExpanding || force) && !chatContents.visible) {
|
||||||
|
chatContents.visible = true
|
||||||
|
}
|
||||||
|
if (!force) previousWidth = width
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: viewNode
|
||||||
|
function onPresented() { chatViewSplitView.restoreSplitViewState() }
|
||||||
|
function onDismissed() { chatViewSplitView.saveSplitViewState() }
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
@ -358,31 +315,18 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessagesResearchPanel {
|
onResizingChanged: if (chatContents.visible) extrasPanel.previousWidth = extrasPanel.width
|
||||||
id: messagesResearchPanel
|
|
||||||
|
|
||||||
visible: false
|
ConversationExtrasPanel {
|
||||||
SplitView.maximumWidth: root.width
|
id: extrasPanel
|
||||||
SplitView.minimumWidth: JamiTheme.detailsPageMinWidth
|
|
||||||
SplitView.preferredWidth: JamiTheme.detailsPageMinWidth
|
|
||||||
}
|
|
||||||
|
|
||||||
SwarmDetailsPanel {
|
property int previousWidth: JamiTheme.extrasPanelMinWidth
|
||||||
id: swarmDetailsPanel
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
SplitView.maximumWidth: root.width
|
SplitView.maximumWidth: root.width
|
||||||
SplitView.preferredWidth: JamiTheme.detailsPageMinWidth
|
SplitView.minimumWidth: JamiTheme.extrasPanelMinWidth
|
||||||
SplitView.minimumWidth: JamiTheme.detailsPageMinWidth
|
SplitView.preferredWidth: JamiTheme.extrasPanelMinWidth
|
||||||
}
|
|
||||||
|
|
||||||
AddMemberPanel {
|
onVisibleChanged: chatViewSplitView.resolvePanes(true)
|
||||||
id: addMemberPanel
|
|
||||||
visible: false
|
|
||||||
|
|
||||||
SplitView.maximumWidth: root.width
|
|
||||||
SplitView.preferredWidth: JamiTheme.detailsPageMinWidth
|
|
||||||
SplitView.minimumWidth: JamiTheme.detailsPageMinWidth
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,15 +37,14 @@ Rectangle {
|
||||||
signal addToConversationClicked
|
signal addToConversationClicked
|
||||||
signal pluginSelector
|
signal pluginSelector
|
||||||
signal showDetailsClicked
|
signal showDetailsClicked
|
||||||
signal searchBarOpened
|
signal searchClicked
|
||||||
signal searchBarClosed
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: CurrentConversation
|
target: CurrentConversation
|
||||||
enabled: true
|
enabled: true
|
||||||
function onTitleChanged() { title.eText = CurrentConversation.title }
|
function onTitleChanged() { title.eText = CurrentConversation.title }
|
||||||
function onDescriptionChanged() { description.eText = CurrentConversation.description }
|
function onDescriptionChanged() { description.eText = CurrentConversation.description }
|
||||||
function onShowDetails() { root.showDetailsClicked() }
|
function onShowSwarmDetails() { root.showDetailsClicked() }
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool interactionButtonsVisibility: {
|
property bool interactionButtonsVisibility: {
|
||||||
|
|
87
src/app/mainview/components/ConversationExtrasPanel.qml
Normal file
87
src/app/mainview/components/ConversationExtrasPanel.qml
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||||
|
*
|
||||||
|
* 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 net.jami.Adapters 1.1
|
||||||
|
|
||||||
|
StackLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property int detailsIndex: -1
|
||||||
|
|
||||||
|
function isOpen(panel) { return visible && currentIndex === panel }
|
||||||
|
|
||||||
|
visible: currentIndex > -1
|
||||||
|
|
||||||
|
property bool detailsShouldOpen: false
|
||||||
|
onVisibleChanged: if (visible) detailsShouldOpen = true
|
||||||
|
|
||||||
|
function restoreState() {
|
||||||
|
// Only applies to Jami accounts, and we musn't be in a call.
|
||||||
|
if (detailsShouldOpen && !inCallView && !CurrentConversation.isSip) {
|
||||||
|
switchToPanel(ChatView.SwarmDetailsPanel, false)
|
||||||
|
} else {
|
||||||
|
closePanel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: CurrentConversationMembers
|
||||||
|
|
||||||
|
function onCountChanged() {
|
||||||
|
// Close the panel if there are 8 or more members in the
|
||||||
|
// conversation AND the "Add Member" panel is currently open.
|
||||||
|
if (CurrentConversationMembers.count >= 8
|
||||||
|
&& isOpen(ChatView.AddMemberPanel)) {
|
||||||
|
closePanel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will open the details panel if it's not already visible.
|
||||||
|
// Additionally, `toggle` being true (default) will close the panel
|
||||||
|
// if it is already open to `panel`.
|
||||||
|
function switchToPanel(panel, toggle=true) {
|
||||||
|
if (visible && toggle && currentIndex === panel) {
|
||||||
|
closePanel()
|
||||||
|
} else {
|
||||||
|
currentIndex = panel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function closePanel() {
|
||||||
|
// We need to close the panel, but not save it when appropriate.
|
||||||
|
currentIndex = -1
|
||||||
|
if (!inCallView && !CurrentConversation.isSip)
|
||||||
|
detailsShouldOpen = false
|
||||||
|
}
|
||||||
|
|
||||||
|
SwarmDetailsPanel {
|
||||||
|
id: detailsPanel
|
||||||
|
|
||||||
|
property int parentIndex: root.currentIndex
|
||||||
|
// When we change to the details panel we should load the tab index.
|
||||||
|
onParentIndexChanged: tabBarIndex = Math.min(tabBarItemsLength - 1,
|
||||||
|
Math.max(0, root.detailsIndex))
|
||||||
|
// Save it when it changes.
|
||||||
|
onTabBarIndexChanged: root.detailsIndex = tabBarIndex
|
||||||
|
}
|
||||||
|
MessagesResearchPanel {}
|
||||||
|
AddMemberPanel {}
|
||||||
|
}
|
|
@ -41,7 +41,9 @@ ListView {
|
||||||
property var messageListModel: MessagesAdapter.mediaMessageListModel
|
property var messageListModel: MessagesAdapter.mediaMessageListModel
|
||||||
readonly property int textType: Interaction.Type.TEXT
|
readonly property int textType: Interaction.Type.TEXT
|
||||||
|
|
||||||
onMessageListModelChanged: sourceModel = root.visible ? messageListModel : null
|
onMessageListModelChanged: sourceModel = root.visible && messageListModel ?
|
||||||
|
messageListModel :
|
||||||
|
null
|
||||||
|
|
||||||
filters: ExpressionFilter {
|
filters: ExpressionFilter {
|
||||||
expression: Type === proxyModel.textType
|
expression: Type === proxyModel.textType
|
||||||
|
|
|
@ -400,6 +400,7 @@ Rectangle {
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: chatViewContainer
|
id: chatViewContainer
|
||||||
|
objectName: "CallViewChatViewContainer"
|
||||||
|
|
||||||
SplitView.preferredHeight: mainColumnLayout.isHorizontal ?
|
SplitView.preferredHeight: mainColumnLayout.isHorizontal ?
|
||||||
root.height :
|
root.height :
|
||||||
|
|
|
@ -28,48 +28,10 @@ import "../../commoncomponents"
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: root
|
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 string currentConversationId: CurrentConversation.id
|
||||||
property bool isOpened: false
|
|
||||||
|
|
||||||
function openSearchBar() {
|
|
||||||
if (isOpened) {
|
|
||||||
textArea.forceActiveFocus()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
searchBarOpened()
|
|
||||||
rectTextArea.isSearch = true
|
|
||||||
anim.start()
|
|
||||||
textArea.forceActiveFocus()
|
|
||||||
isOpened = true
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeSearchbar() {
|
|
||||||
if (!isOpened)
|
|
||||||
return
|
|
||||||
searchBarClosed()
|
|
||||||
rectTextArea.isSearch = false
|
|
||||||
anim.start()
|
|
||||||
isOpened = false
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: chatViewHeader
|
|
||||||
function onShowDetailsClicked() {
|
|
||||||
if (rectTextArea.isSearch)
|
|
||||||
closeSearchbar()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onCurrentConversationIdChanged: {
|
|
||||||
if (isOpened)
|
|
||||||
closeSearchbar()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
property bool isOpen: extrasPanel.isOpen(ChatView.MessagesResearchPanel)
|
||||||
|
onIsOpenChanged: if (isOpen) textArea.forceActiveFocus()
|
||||||
|
|
||||||
PushButton {
|
PushButton {
|
||||||
id: startSearchMessages
|
id: startSearchMessages
|
||||||
|
@ -78,66 +40,26 @@ RowLayout {
|
||||||
normalColor: JamiTheme.chatviewBgColor
|
normalColor: JamiTheme.chatviewBgColor
|
||||||
imageColor: JamiTheme.chatviewButtonColor
|
imageColor: JamiTheme.chatviewButtonColor
|
||||||
|
|
||||||
onClicked: {
|
onClicked: chatViewHeader.searchClicked()
|
||||||
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 {
|
Rectangle {
|
||||||
id: rectTextArea
|
id: rectTextArea
|
||||||
|
|
||||||
visible: false
|
|
||||||
Layout.preferredHeight: startSearchMessages.height
|
Layout.preferredHeight: startSearchMessages.height
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: JamiTheme.chatviewTextColor
|
border.color: JamiTheme.chatviewTextColor
|
||||||
radius: 10
|
radius: 10
|
||||||
border.width: 2
|
border.width: 2
|
||||||
|
|
||||||
property bool isSearch: false
|
opacity: isOpen
|
||||||
property int textAreaWidth: 200
|
visible: opacity
|
||||||
property alias searchBarWidth: root.searchBarWidth
|
Behavior on opacity { NumberAnimation { duration: 150 } }
|
||||||
|
|
||||||
onSearchBarWidthChanged: {
|
Layout.preferredWidth: isOpen ? JamiTheme.searchbarSize : 0
|
||||||
Layout.preferredWidth = root.searchBarWidth
|
Behavior on Layout.preferredWidth { NumberAnimation { duration: 150 } }
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
TextField {
|
||||||
id: textArea
|
id: textArea
|
||||||
|
|
|
@ -32,6 +32,9 @@ import "../../settingsview/components"
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property alias tabBarIndex: tabBar.currentIndex
|
||||||
|
property int tabBarItemsLength: tabBar.contentChildren.length
|
||||||
|
|
||||||
color: CurrentConversation.color
|
color: CurrentConversation.color
|
||||||
property var isAdmin: !CurrentConversation.isCoreDialog &&
|
property var isAdmin: !CurrentConversation.isCoreDialog &&
|
||||||
UtilsAdapter.getParticipantRole(CurrentAccount.id,
|
UtilsAdapter.getParticipantRole(CurrentAccount.id,
|
||||||
|
@ -193,74 +196,71 @@ Rectangle {
|
||||||
|
|
||||||
currentIndex: 0
|
currentIndex: 0
|
||||||
|
|
||||||
onVisibleChanged: {
|
|
||||||
tabBar.currentIndex = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Layout.preferredWidth: root.width
|
Layout.preferredWidth: root.width
|
||||||
Layout.preferredHeight: settingsTabButton.height
|
Layout.preferredHeight: settingsTabButton.height
|
||||||
|
|
||||||
FilterTabButton {
|
property string currentItemName: itemAt(currentIndex).objectName
|
||||||
id: settingsTabButton
|
|
||||||
|
component DetailsTabButton: FilterTabButton {
|
||||||
backgroundColor: CurrentConversation.color
|
backgroundColor: CurrentConversation.color
|
||||||
hoverColor: CurrentConversation.color
|
hoverColor: CurrentConversation.color
|
||||||
borderWidth: 4
|
borderWidth: 4
|
||||||
bottomMargin: JamiTheme.settingsMarginSize
|
bottomMargin: JamiTheme.settingsMarginSize
|
||||||
fontSize: JamiTheme.menuFontSize
|
fontSize: JamiTheme.menuFontSize
|
||||||
underlineContentOnly: true
|
underlineContentOnly: true
|
||||||
|
textColorHovered: UtilsAdapter.luma(root.color) ?
|
||||||
textColorHovered: UtilsAdapter.luma(root.color) ? JamiTheme.placeholderTextColorWhite : JamiTheme.placeholderTextColor
|
JamiTheme.placeholderTextColorWhite :
|
||||||
|
JamiTheme.placeholderTextColor
|
||||||
textColor: UtilsAdapter.luma(root.color) ?
|
textColor: UtilsAdapter.luma(root.color) ?
|
||||||
JamiTheme.chatviewTextColorLight :
|
JamiTheme.chatviewTextColorLight :
|
||||||
JamiTheme.chatviewTextColorDark
|
JamiTheme.chatviewTextColorDark
|
||||||
|
|
||||||
down: tabBar.currentIndex === 0
|
|
||||||
labelText: JamiStrings.settings
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
down: tabBar.currentIndex === TabBar.index
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterTabButton {
|
function addRemoveButtons() {
|
||||||
id: membersTabButton
|
if (CurrentConversation.isCoreDialog) {
|
||||||
visible: !CurrentConversation.isCoreDialog
|
if (tabBar.contentChildren.length === 3)
|
||||||
Layout.fillWidth: true
|
tabBar.removeItem(tabBar.itemAt(1))
|
||||||
width: visible ? tabBar.width/3 : 0
|
} else {
|
||||||
backgroundColor: CurrentConversation.color
|
if (tabBar.contentChildren.length === 2) {
|
||||||
hoverColor: CurrentConversation.color
|
const obj = membersTabButtonComp.createObject(tabBar)
|
||||||
borderWidth: 4
|
tabBar.insertItem(1, obj)
|
||||||
bottomMargin: JamiTheme.settingsMarginSize
|
}
|
||||||
fontSize: JamiTheme.menuFontSize
|
|
||||||
underlineContentOnly: true
|
|
||||||
|
|
||||||
textColorHovered: UtilsAdapter.luma(root.color) ? JamiTheme.placeholderTextColorWhite : JamiTheme.placeholderTextColor
|
|
||||||
textColor: UtilsAdapter.luma(root.color) ?
|
|
||||||
JamiTheme.chatviewTextColorLight :
|
|
||||||
JamiTheme.chatviewTextColorDark
|
|
||||||
|
|
||||||
down: tabBar.currentIndex === 1
|
|
||||||
labelText: {
|
|
||||||
var membersNb = CurrentConversationMembers.count;
|
|
||||||
if (membersNb > 1)
|
|
||||||
return JamiStrings.members.arg(membersNb)
|
|
||||||
return JamiStrings.member
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FilterTabButton {
|
Component.onCompleted: addRemoveButtons()
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: CurrentConversation
|
||||||
|
function onIsCoreDialogChanged() { tabBar.addRemoveButtons() }
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: membersTabButtonComp
|
||||||
|
DetailsTabButton {
|
||||||
|
id: membersTabButton
|
||||||
|
objectName: "members"
|
||||||
|
visible: !CurrentConversation.isCoreDialog
|
||||||
|
labelText: {
|
||||||
|
var membersNb = CurrentConversationMembers.count;
|
||||||
|
if (membersNb > 1)
|
||||||
|
return JamiStrings.members.arg(membersNb)
|
||||||
|
return JamiStrings.member
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DetailsTabButton {
|
||||||
|
id: settingsTabButton
|
||||||
|
objectName: "settings"
|
||||||
|
labelText: JamiStrings.settings
|
||||||
|
}
|
||||||
|
|
||||||
|
DetailsTabButton {
|
||||||
id: documentsTabButton
|
id: documentsTabButton
|
||||||
backgroundColor: CurrentConversation.color
|
objectName: "documents"
|
||||||
hoverColor: CurrentConversation.color
|
|
||||||
borderWidth: 4
|
|
||||||
bottomMargin: JamiTheme.settingsMarginSize
|
|
||||||
fontSize: JamiTheme.menuFontSize
|
|
||||||
underlineContentOnly: true
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
textColorHovered: UtilsAdapter.luma(root.color) ? JamiTheme.placeholderTextColorWhite : JamiTheme.placeholderTextColor
|
|
||||||
textColor: UtilsAdapter.luma(root.color) ?
|
|
||||||
JamiTheme.chatviewTextColorLight :
|
|
||||||
JamiTheme.chatviewTextColorDark
|
|
||||||
|
|
||||||
down: tabBar.currentIndex === 2
|
|
||||||
labelText: JamiStrings.documents
|
labelText: JamiStrings.documents
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,7 +298,7 @@ Rectangle {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: JamiTheme.settingsMarginSize
|
anchors.rightMargin: JamiTheme.settingsMarginSize
|
||||||
visible: tabBar.currentIndex === 0
|
visible: tabBar.currentItemName === "settings"
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
|
|
||||||
SwarmDetailsItem {
|
SwarmDetailsItem {
|
||||||
|
@ -589,7 +589,7 @@ Rectangle {
|
||||||
anchors.bottomMargin: JamiTheme.preferredMarginSize
|
anchors.bottomMargin: JamiTheme.preferredMarginSize
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
visible: tabBar.currentIndex === 1
|
visible: tabBar.currentItemName === "members"
|
||||||
|
|
||||||
SwarmParticipantContextMenu {
|
SwarmParticipantContextMenu {
|
||||||
id: contextMenu
|
id: contextMenu
|
||||||
|
@ -708,7 +708,7 @@ Rectangle {
|
||||||
id: documents
|
id: documents
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
visible: tabBar.currentIndex === 2
|
visible: tabBar.currentItemName === "documents"
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue