Skip to content
Snippets Groups Projects
Unverified Commit 76896e79 authored by Sébastien Blin's avatar Sébastien Blin
Browse files

chatview: add the swarm details page in a stackview

This allow the swarm details page to be resizable.

Also adds the add members list into this view.
Presence and filtering for ContactPicker is also
fixed.

GitLab: #670
Change-Id: I4bf4369eba1d30dff3931575cd8ebd7eb2c7aee0
parent f45fda36
No related branches found
No related tags found
No related merge requests found
......@@ -112,6 +112,7 @@
<file>src/mainview/components/CallViewContextMenu.qml</file>
<file>src/mainview/components/UserProfile.qml</file>
<file>src/mainview/components/SwarmDetailsPanel.qml</file>
<file>src/mainview/components/AddMemberPanel.qml</file>
<file>src/mainview/components/SelectScreen.qml</file>
<file>src/mainview/components/ScreenRubberBand.qml</file>
<file>src/mainview/components/ContactPicker.qml</file>
......
......@@ -368,6 +368,9 @@ Item {
property real mainViewPreferredWidth: 725
property real mainViewPreferredHeight: 600
// Details page
property real detailsPageMinWidth: 300
function setTheme(dark) {
darkTheme = dark
}
......
......@@ -32,6 +32,18 @@ ContactAdapter::ContactAdapter(LRCInstance* instance, QObject* parent)
}
}
bool
ContactAdapter::hasDifferentMembers(const VectorString& currentMembers,
const VectorString& convMembers) const
{
for (const auto& uri : convMembers) {
if (uri != lrcInstance_->getCurrentAccountInfo().profileInfo.uri
&& !currentMembers.contains(uri))
return true;
}
return false;
}
QVariant
ContactAdapter::getContactSelectableModel(int type)
{
......@@ -54,11 +66,16 @@ ContactAdapter::getContactSelectableModel(int type)
return !defaultModerators_.contains(index.data(Role::URI).toString());
});
break;
case SmartListModel::Type::ADDCONVMEMBER:
selectableProxyModel_->setPredicate([](const QModelIndex& index, const QRegularExpression&) {
return index.data(Role::IsCoreDialog).toBool();
});
case SmartListModel::Type::ADDCONVMEMBER: {
auto currentConvID = lrcInstance_->get_selectedConvUid();
auto* convModel = lrcInstance_->getCurrentConversationModel();
auto members = convModel->peersForConversation(currentConvID);
selectableProxyModel_->setPredicate(
[this, members](const QModelIndex& index, const QRegularExpression&) {
return hasDifferentMembers(members, index.data(Role::Uris).toStringList());
});
break;
}
case SmartListModel::Type::CONFERENCE:
selectableProxyModel_->setPredicate([](const QModelIndex& index, const QRegularExpression&) {
return index.data(Role::Presence).toBool();
......@@ -107,15 +124,18 @@ ContactAdapter::setSearchFilter(const QString& filter)
&& index.data(Role::Title).toString().contains(filter));
});
} else if (listModeltype_ == SmartListModel::Type::ADDCONVMEMBER) {
selectableProxyModel_->setPredicate(
[this, filter](const QModelIndex& index, const QRegularExpression&) {
return (index.data(Role::Title).toString().contains(filter, Qt::CaseInsensitive)
|| index.data(Role::RegisteredName)
.toString()
.contains(filter, Qt::CaseInsensitive)
|| index.data(Role::URI).toString().contains(filter, Qt::CaseInsensitive))
&& index.data(Role::IsCoreDialog).toBool();
});
auto currentConvID = lrcInstance_->get_selectedConvUid();
auto* convModel = lrcInstance_->getCurrentConversationModel();
auto members = convModel->peersForConversation(currentConvID);
selectableProxyModel_->setPredicate([this, filter, members](const QModelIndex& index,
const QRegularExpression&) {
return hasDifferentMembers(members, index.data(Role::Uris).toStringList())
&& (index.data(Role::Title).toString().contains(filter, Qt::CaseInsensitive)
|| index.data(Role::RegisteredName)
.toString()
.contains(filter, Qt::CaseInsensitive)
|| index.data(Role::Uris).toString().contains(filter, Qt::CaseInsensitive));
});
}
selectableProxyModel_->setFilterRegularExpression(
QRegularExpression(filter, QRegularExpression::CaseInsensitiveOption));
......@@ -132,8 +152,16 @@ ContactAdapter::contactSelected(int index)
if (contactIndex.isValid()) {
switch (listModeltype_) {
case SmartListModel::Type::ADDCONVMEMBER: {
const auto uri = contactIndex.data(Role::URI).value<QString>();
convModel->addConversationMember(lrcInstance_->get_selectedConvUid(), uri);
auto members = convModel->peersForConversation(lrcInstance_->get_selectedConvUid());
auto cntMembers = members.size();
const auto uris = contactIndex.data(Role::Uris).toStringList();
for (const auto& uri : uris) {
// TODO remove < 9
if (!members.contains(uri) && cntMembers < 9) {
cntMembers++;
convModel->addConversationMember(lrcInstance_->get_selectedConvUid(), uri);
}
}
break;
}
case SmartListModel::Type::CONFERENCE: {
......
......@@ -104,6 +104,8 @@ private:
QStringList defaultModerators_;
bool hasDifferentMembers(const VectorString& currentMembers, const VectorString& convMembers) const;
Q_SIGNALS:
void defaultModeratorsUpdated();
};
/*
* Copyright (C) 2022 by Savoir-faire Linux
* Author: Sébastien Blin <sebastien.blin@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 net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import "../../commoncomponents"
Rectangle {
id: root
color: JamiTheme.backgroundColor
property int type: ContactList.ADDCONVMEMBER
width: 250
ColumnLayout {
id: contactPickerPopupRectColumnLayout
anchors.top: root.top
anchors.bottom: root.bottom
anchors.margins: 16
ContactSearchBar {
id: contactPickerContactSearchBar
Layout.alignment: Qt.AlignCenter
Layout.margins: 5
Layout.fillWidth: true
Layout.preferredHeight: 35
placeHolderText: JamiStrings.addParticipant
onContactSearchBarTextChanged: {
ContactAdapter.setSearchFilter(text)
}
}
JamiListView {
id: contactPickerListView
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: root.width - 8
Layout.preferredHeight: contactPickerPopupRectColumnLayout.height - contactPickerContactSearchBar.height
model: ContactAdapter.getContactSelectableModel(type)
Connections {
enabled: visible
target: CurrentConversation
onUrisChanged: {
model = ContactAdapter.getContactSelectableModel(type)
}
}
onVisibleChanged: {
if (visible)
model = ContactAdapter.getContactSelectableModel(type)
}
delegate: ContactPickerItemDelegate {
id: contactPickerItemDelegate
showPresenceIndicator: true
}
}
}
}
......@@ -44,6 +44,7 @@ Rectangle {
function focusChatView() {
chatViewFooter.textInput.forceActiveFocus()
swarmDetailsPanel.visible = false
addMemberPanel.visible = false
}
color: JamiTheme.chatviewBgColor
......@@ -78,9 +79,26 @@ Rectangle {
}
onShowDetailsClicked: {
addMemberPanel.visible = false
swarmDetailsPanel.visible = !swarmDetailsPanel.visible
}
Connections {
target: CurrentConversation
onUrisChanged: {
if (CurrentConversation.uris.length >= 8 && addMemberPanel.visible) {
swarmDetailsPanel.visible = false
addMemberPanel.visible = !addMemberPanel.visible
}
}
}
onAddToConversationClicked: {
swarmDetailsPanel.visible = false
addMemberPanel.visible = !addMemberPanel.visible
}
onPluginSelector: {
// Create plugin handler picker - PLUGINS
PluginHandlerPickerCreation.createPluginHandlerPickerObjects(
......@@ -91,14 +109,27 @@ Rectangle {
}
}
RowLayout {
SplitView {
id: chatViewMainRow
Layout.fillWidth: true
Layout.fillHeight: true
handle: Rectangle {
implicitWidth: JamiTheme.splitViewHandlePreferredWidth
implicitHeight: splitView.height
color: JamiTheme.primaryBackgroundColor
Rectangle {
implicitWidth: 1
implicitHeight: splitView.height
color: JamiTheme.tabbarBorderColor
}
}
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
SplitView.maximumWidth: splitView.width
// Note, without JamiTheme.detailsPageMinWidth, sometimes the details page is hidden at the right
SplitView.preferredWidth: Math.max(0, 2 * splitView.width / 3 - JamiTheme.detailsPageMinWidth)
SplitView.fillHeight: true
StackLayout {
id: chatViewStack
......@@ -162,6 +193,23 @@ Rectangle {
SwarmDetailsPanel {
id: swarmDetailsPanel
visible: false
SplitView.maximumWidth: splitView.width
SplitView.preferredWidth: Math.max(JamiTheme.detailsPageMinWidth, splitView.width / 3)
SplitView.minimumWidth: JamiTheme.detailsPageMinWidth
SplitView.fillHeight: true
Layout.fillHeight: true
Layout.fillWidth: true
}
AddMemberPanel {
id: addMemberPanel
visible: false
SplitView.maximumWidth: splitView.width
SplitView.preferredWidth: Math.max(JamiTheme.detailsPageMinWidth, splitView.width / 3)
SplitView.minimumWidth: JamiTheme.detailsPageMinWidth
SplitView.fillHeight: true
Layout.fillHeight: true
Layout.fillWidth: true
}
......
......@@ -25,7 +25,6 @@ import net.jami.Constants 1.1
import net.jami.Adapters 1.1
import "../../commoncomponents"
import "../js/contactpickercreation.js" as ContactPickerCreation
Rectangle {
id: root
......@@ -35,6 +34,7 @@ Rectangle {
signal backClicked
signal needToHideConversationInCall
signal addToConversationClicked
signal pluginSelector
signal showDetailsClicked
......@@ -61,11 +61,6 @@ Rectangle {
color: JamiTheme.chatviewBgColor
function addToConversationClicked() {
ContactPickerCreation.createContactPickerObjects(ContactList.ADDCONVMEMBER, root)
ContactPickerCreation.openContactPicker()
}
RowLayout {
id: messagingHeaderRectRowLayout
......@@ -185,15 +180,15 @@ Rectangle {
PushButton {
id: addParticipantsButton
visible: addMemberVisibility
source: JamiResources.add_people_24dp_svg
toolTipText: JamiStrings.addParticipants
normalColor: JamiTheme.chatviewBgColor
imageColor: JamiTheme.chatviewButtonColor
onClicked: root.addToConversationClicked()
visible: CurrentConversation.uris.length < 8 && addMemberVisibility
onClicked: addToConversationClicked()
}
PushButton {
......
......@@ -28,7 +28,9 @@ import "../../commoncomponents"
ItemDelegate {
id: contactPickerItemDelegate
property alias showPresenceIndicator: avatar.showPresenceIndicator
property var showPresenceIndicator: false
signal contactClicked
ConversationAvatar {
id: avatar
......@@ -41,6 +43,8 @@ ItemDelegate {
height: 40
imageId: UID
showPresenceIndicator: contactPickerItemDelegate.showPresenceIndicator && Presence
}
Rectangle {
......@@ -102,7 +106,7 @@ ItemDelegate {
color: JamiTheme.backgroundColor
implicitWidth: contactPickerPopupRect.width
implicitWidth: root.width
implicitHeight: Math.max(
contactPickerContactName.height
+ textMetricsContactPickerContactId.height + 10,
......@@ -125,7 +129,10 @@ ItemDelegate {
itemSmartListBackground.color = JamiTheme.normalButtonColor
ContactAdapter.contactSelected(index)
contactPickerPopup.close()
root.contactClicked()
// TODO remove from there
if (contactPickerPopup)
contactPickerPopup.close()
}
onEntered: {
......
/*
* Copyright (C) 2021 by Savoir-faire Linux
* Copyright (C) 2022 by Savoir-faire Linux
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment