diff --git a/qml.qrc b/qml.qrc
index 9dca240a..e3d6305b 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -94,6 +94,7 @@
src/mainview/components/SidePanel.qml
src/mainview/components/WelcomePage.qml
src/mainview/components/ChatView.qml
+ src/mainview/components/NewSwarmPage.qml
src/mainview/components/ChatViewHeader.qml
src/mainview/components/AccountComboBox.qml
src/mainview/components/CallStackView.qml
@@ -109,6 +110,7 @@
src/mainview/components/ConversationSmartListContextMenu.qml
src/mainview/components/CallViewContextMenu.qml
src/mainview/components/UserProfile.qml
+ src/mainview/components/SwarmDetailsPanel.qml
src/mainview/components/SelectScreen.qml
src/mainview/components/ScreenRubberBand.qml
src/mainview/components/ContactPicker.qml
diff --git a/resources/icons/swarm_details_panel.svg b/resources/icons/swarm_details_panel.svg
new file mode 100644
index 00000000..2a302f23
--- /dev/null
+++ b/resources/icons/swarm_details_panel.svg
@@ -0,0 +1,15 @@
+
+
+
diff --git a/src/constant/JamiStrings.qml b/src/constant/JamiStrings.qml
index d0db3dce..44196c6f 100644
--- a/src/constant/JamiStrings.qml
+++ b/src/constant/JamiStrings.qml
@@ -222,6 +222,7 @@ Item {
property string resumeVideo: qsTr("Resume video")
property string addParticipant: qsTr("Add participant")
property string addParticipants: qsTr("Add participants")
+ property string details: qsTr("Details")
property string chat: qsTr("Chat")
property string moreOptions: qsTr("More options")
property string mosaic: qsTr("Mosaic")
@@ -609,4 +610,13 @@ Item {
property string invitationViewJoinConversation: qsTr("Hello,\nWould you like to join the conversation?")
property string invitationViewAcceptedConversation: qsTr("You have accepted\nthe conversation request")
property string invitationViewWaitingForSync: qsTr("Waiting until %1\nconnects to synchronize the conversation.")
+
+ // SwarmDetailsPanel
+ property string about: qsTr("About")
+ property string members: qsTr("Members")
+ property string documents: qsTr("Documents")
+
+ // NewSwarmPage
+
+ property string createTheSwarm: qsTr("Create the swarm")
}
diff --git a/src/contactadapter.cpp b/src/contactadapter.cpp
index 534ba666..6ae89c87 100644
--- a/src/contactadapter.cpp
+++ b/src/contactadapter.cpp
@@ -55,7 +55,7 @@ ContactAdapter::getContactSelectableModel(int type)
});
break;
case SmartListModel::Type::ADDCONVMEMBER:
- selectableProxyModel_->setPredicate([](const QModelIndex& index, const QRegExp&) {
+ selectableProxyModel_->setPredicate([](const QModelIndex& index, const QRegularExpression&) {
return index.data(Role::IsCoreDialog).toBool();
});
break;
@@ -108,7 +108,7 @@ ContactAdapter::setSearchFilter(const QString& filter)
});
} else if (listModeltype_ == SmartListModel::Type::ADDCONVMEMBER) {
selectableProxyModel_->setPredicate(
- [this, filter](const QModelIndex& index, const QRegExp&) {
+ [this, filter](const QModelIndex& index, const QRegularExpression&) {
return (index.data(Role::Title).toString().contains(filter, Qt::CaseInsensitive)
|| index.data(Role::RegisteredName)
.toString()
diff --git a/src/conversationsadapter.cpp b/src/conversationsadapter.cpp
index 02786c58..5e87e005 100644
--- a/src/conversationsadapter.cpp
+++ b/src/conversationsadapter.cpp
@@ -480,6 +480,25 @@ ConversationsAdapter::restartConversation(const QString& convId)
accInfo.contactModel->removeContact(peerUri);
}
+void
+ConversationsAdapter::updateConversationTitle(const QString& convId, const QString& newTitle)
+{
+ auto convModel = lrcInstance_->getCurrentConversationModel();
+ QMap details;
+ details["title"] = newTitle;
+ convModel->updateConversationInfo(convId, details);
+}
+
+void
+ConversationsAdapter::updateConversationDescription(const QString& convId,
+ const QString& newDescription)
+{
+ auto convModel = lrcInstance_->getCurrentConversationModel();
+ QMap details;
+ details["description"] = newDescription;
+ convModel->updateConversationInfo(convId, details);
+}
+
bool
ConversationsAdapter::connectConversationModel()
{
diff --git a/src/conversationsadapter.h b/src/conversationsadapter.h
index 72da591e..d9a7bc5d 100644
--- a/src/conversationsadapter.h
+++ b/src/conversationsadapter.h
@@ -52,6 +52,9 @@ public:
Q_INVOKABLE void setFilter(const QString& filterString);
Q_INVOKABLE QVariantMap getConvInfoMap(const QString& convId);
Q_INVOKABLE void restartConversation(const QString& convId);
+ Q_INVOKABLE void updateConversationTitle(const QString& convId, const QString& newTitle);
+ Q_INVOKABLE void updateConversationDescription(const QString& convId,
+ const QString& newDescription);
Q_SIGNALS:
void showConversation(const QString& accountId, const QString& convUid);
diff --git a/src/currentconversation.cpp b/src/currentconversation.cpp
index 3a94d6fd..21ee8f43 100644
--- a/src/currentconversation.cpp
+++ b/src/currentconversation.cpp
@@ -51,6 +51,7 @@ CurrentConversation::updateData()
if (auto optConv = accInfo.conversationModel->getConversationForUid(convId)) {
auto& convInfo = optConv->get();
set_title(accInfo.conversationModel->title(convId));
+ set_description(accInfo.conversationModel->description(convId));
set_uris(accInfo.conversationModel->peersForConversation(convId).toList());
set_isSwarm(convInfo.isSwarm());
set_isLegacy(convInfo.isLegacy());
diff --git a/src/currentconversation.h b/src/currentconversation.h
index d57b5737..0ad13d40 100644
--- a/src/currentconversation.h
+++ b/src/currentconversation.h
@@ -31,6 +31,7 @@ class CurrentConversation final : public QObject
Q_OBJECT
QML_PROPERTY(QString, id)
QML_PROPERTY(QString, title)
+ QML_PROPERTY(QString, description)
QML_PROPERTY(QStringList, uris)
QML_PROPERTY(bool, isSwarm)
QML_PROPERTY(bool, isLegacy)
diff --git a/src/mainview/MainView.qml b/src/mainview/MainView.qml
index 0c119124..353ec1a0 100644
--- a/src/mainview/MainView.qml
+++ b/src/mainview/MainView.qml
@@ -80,6 +80,8 @@ Rectangle {
if (isPageInStack("callStackViewObject", sidePanelViewStack) ||
isPageInStack("chatView", sidePanelViewStack) ||
isPageInStack("chatView", mainViewStack) ||
+ isPageInStack("newSwarmPage", sidePanelViewStack) ||
+ isPageInStack("newSwarmPage", mainViewStack) ||
isPageInStack("callStackViewObject", mainViewStack)) {
sidePanelViewStack.pop(StackView.Immediate)
mainViewStack.pop(welcomePage, StackView.Immediate)
@@ -107,6 +109,16 @@ Rectangle {
}
}
+ function pushNewSwarmPage() {
+ if (sidePanelOnly) {
+ sidePanelViewStack.pop(StackView.Immediate)
+ sidePanelViewStack.push(newSwarmPage, StackView.Immediate)
+ } else {
+ mainViewStack.pop(welcomePage, StackView.Immediate)
+ mainViewStack.push(newSwarmPage, StackView.Immediate)
+ }
+ }
+
function startWizard() {
mainViewStackLayout.currentIndex = 1
}
@@ -353,6 +365,11 @@ Rectangle {
function onNavigateToWelcomePageRequested() {
backToMainView()
}
+
+ }
+
+ onCreateSwarmClicked: {
+ pushNewSwarmPage()
}
}
@@ -394,6 +411,18 @@ Rectangle {
Component.onCompleted: MessagesAdapter.setQmlObject(this)
}
+ NewSwarmPage {
+ id: newSwarmPage
+
+ objectName: "newSwarmPage"
+ visible: false
+
+ onCreateSwarmClicked: {
+ console.warn("@@@")
+ backToMainView()
+ }
+ }
+
onWidthChanged: {
// Hide unnecessary stackview when width is changed.
var widthToCompare = previousWidth < mainView.width ?
diff --git a/src/mainview/components/ChatView.qml b/src/mainview/components/ChatView.qml
index 2077ddcf..1ff47393 100644
--- a/src/mainview/components/ChatView.qml
+++ b/src/mainview/components/ChatView.qml
@@ -53,7 +53,7 @@ Rectangle {
spacing: 0
ChatViewHeader {
- id: messageWebViewHeader
+ id: chatViewHeader
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
@@ -76,6 +76,10 @@ Rectangle {
root.needToHideConversationInCall()
}
+ onShowDetailsClicked: {
+ swarmDetailsPanel.visible = !swarmDetailsPanel.visible
+ }
+
onPluginSelector: {
// Create plugin handler picker - PLUGINS
PluginHandlerPickerCreation.createPluginHandlerPickerObjects(
@@ -86,22 +90,67 @@ Rectangle {
}
}
- StackLayout {
- id: chatViewStack
-
- Layout.alignment: Qt.AlignHCenter
+ RowLayout {
+ id: chatViewMainRow
Layout.fillWidth: true
- Layout.maximumWidth: JamiTheme.chatViewMaximumWidth
Layout.fillHeight: true
- Layout.topMargin: JamiTheme.chatViewHairLineSize
- Layout.bottomMargin: JamiTheme.chatViewHairLineSize
- currentIndex: CurrentConversation.isRequest ||
- CurrentConversation.needsSyncing
+ ColumnLayout {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ StackLayout {
+ id: chatViewStack
+
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Layout.maximumWidth: JamiTheme.chatViewMaximumWidth
+ Layout.topMargin: JamiTheme.chatViewHairLineSize
+ Layout.bottomMargin: JamiTheme.chatViewHairLineSize
+
+ currentIndex: CurrentConversation.isRequest ||
+ CurrentConversation.needsSyncing
+
+ Loader {
+ active: CurrentConversation.id !== ""
+ sourceComponent: MessageListView {
+ DropArea {
+ anchors.fill: parent
+ onDropped: chatViewFooter.setFilePathsToSend(drop.urls)
+ }
+ }
+ }
+
+ InvitationView {
+ id: invitationView
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ }
+
+ ReadOnlyFooter {
+ visible: CurrentConversation.readOnly
+ Layout.fillWidth: true
+ }
+
+ ChatViewFooter {
+ id: chatViewFooter
+
+ visible: {
+ if (CurrentConversation.needsSyncing || CurrentConversation.readOnly)
+ return false
+ else if (CurrentConversation.isSwarm && CurrentConversation.isRequest)
+ return false
+ return true
+ }
+
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+ Layout.preferredHeight: implicitHeight
+ Layout.maximumHeight: JamiTheme.chatViewFooterMaximumHeight
- Loader {
- active: CurrentConversation.id !== ""
- sourceComponent: MessageListView {
DropArea {
anchors.fill: parent
onDropped: chatViewFooter.setFilePathsToSend(drop.urls)
@@ -109,38 +158,11 @@ Rectangle {
}
}
- InvitationView {
- id: invitationView
-
- Layout.fillWidth: true
+ SwarmDetailsPanel {
+ id: swarmDetailsPanel
+ visible: false
Layout.fillHeight: true
- }
- }
-
- ReadOnlyFooter {
- visible: CurrentConversation.readOnly
- Layout.fillWidth: true
- }
-
- ChatViewFooter {
- id: chatViewFooter
-
- visible: {
- if (CurrentConversation.needsSyncing || CurrentConversation.readOnly)
- return false
- else if (CurrentConversation.isSwarm && CurrentConversation.isRequest)
- return false
- return true
- }
-
- Layout.alignment: Qt.AlignHCenter
- Layout.fillWidth: true
- Layout.preferredHeight: implicitHeight
- Layout.maximumHeight: JamiTheme.chatViewFooterMaximumHeight
-
- DropArea {
- anchors.fill: parent
- onDropped: chatViewFooter.setFilePathsToSend(drop.urls)
+ Layout.fillWidth: true
}
}
}
diff --git a/src/mainview/components/ChatViewHeader.qml b/src/mainview/components/ChatViewHeader.qml
index 50053eea..ff0cdcd1 100644
--- a/src/mainview/components/ChatViewHeader.qml
+++ b/src/mainview/components/ChatViewHeader.qml
@@ -36,6 +36,7 @@ Rectangle {
signal backClicked
signal needToHideConversationInCall
signal pluginSelector
+ signal showDetailsClicked
property bool interactionButtonsVisibility: {
if (CurrentConversation.inCall)
@@ -51,6 +52,10 @@ Rectangle {
}
property bool addMemberVisibility: {
+ return swarmDetailsVisibility && !CurrentConversation.isRequest
+ }
+
+ property bool swarmDetailsVisibility: {
return !CurrentConversation.isCoreDialog && CurrentConversation.isSwarm
}
@@ -146,6 +151,7 @@ Rectangle {
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
Layout.fillWidth: true
Layout.rightMargin: 8
+ spacing: 16
PushButton {
id: startAAudioCallButton
@@ -218,6 +224,20 @@ Rectangle {
onClicked: MessagesAdapter.sendConversationRequest()
}
+
+ PushButton {
+ id: detailsButton
+
+ visible: swarmDetailsVisibility
+
+ source: JamiResources.swarm_details_panel_svg
+ toolTipText: JamiStrings.details
+
+ normalColor: JamiTheme.chatviewBgColor
+ imageColor: JamiTheme.chatviewButtonColor
+
+ onClicked: showDetailsClicked()
+ }
}
}
diff --git a/src/mainview/components/NewSwarmPage.qml b/src/mainview/components/NewSwarmPage.qml
new file mode 100644
index 00000000..7400e76b
--- /dev/null
+++ b/src/mainview/components/NewSwarmPage.qml
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2021 by Savoir-faire Linux
+ * Author: Sébastien Blin
+ *
+ * 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 .
+ */
+
+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.chatviewBgColor
+
+ signal createSwarmClicked
+
+ RowLayout {
+ id: mainLayout
+
+ anchors.fill: parent
+
+ MaterialButton {
+ id: btnCreateSwarm
+
+ preferredWidth: JamiTheme.aboutButtonPreferredWidth
+
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
+ color: JamiTheme.buttonTintedBlue
+ hoveredColor: JamiTheme.buttonTintedBlueHovered
+ pressedColor: JamiTheme.buttonTintedBluePressed
+
+ text: JamiStrings.createTheSwarm
+
+ onClicked: {
+ ConversationsAdapter.createSwarm()
+ createSwarmClicked()
+ }
+ }
+ }
+}
diff --git a/src/mainview/components/SidePanel.qml b/src/mainview/components/SidePanel.qml
index f0ad5fcb..9fbe8d0e 100644
--- a/src/mainview/components/SidePanel.qml
+++ b/src/mainview/components/SidePanel.qml
@@ -31,6 +31,8 @@ Rectangle {
color: JamiTheme.backgroundColor
+ signal createSwarmClicked
+
Connections {
target: LRCInstance
@@ -105,7 +107,7 @@ Rectangle {
toolTipText: JamiStrings.startASwarm
onClicked: {
- ConversationsAdapter.createSwarm()
+ createSwarmClicked()
}
}
}
diff --git a/src/mainview/components/SwarmDetailsPanel.qml b/src/mainview/components/SwarmDetailsPanel.qml
new file mode 100644
index 00000000..88468a79
--- /dev/null
+++ b/src/mainview/components/SwarmDetailsPanel.qml
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2021 by Savoir-faire Linux
+ * Author: Sébastien Blin
+ *
+ * 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 .
+ */
+
+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.buttonTintedBlue
+
+ ColumnLayout {
+ id: swarmProfileDetails
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ ConversationAvatar {
+ id: conversationAvatar
+
+ Layout.alignment: Qt.AlignCenter
+ Layout.preferredWidth: JamiTheme.avatarSizeInCall
+ Layout.preferredHeight: JamiTheme.avatarSizeInCall
+
+ imageId: LRCInstance.selectedConvUid
+
+ showPresenceIndicator: false
+ }
+
+ MaterialLineEdit {
+ Layout.alignment: Qt.AlignCenter
+ Layout.topMargin: JamiTheme.preferredMarginSize
+
+ Layout.preferredWidth: root.width
+
+ font.pointSize: JamiTheme.titleFontSize
+
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ text: CurrentConversation.title
+ color: "white"
+
+ onEditingFinished: {
+ ConversationsAdapter.updateConversationTitle(LRCInstance.selectedConvUid, this.text)
+ }
+ }
+
+ MaterialLineEdit {
+ Layout.alignment: Qt.AlignCenter
+ Layout.topMargin: JamiTheme.preferredMarginSize
+
+ Layout.preferredWidth: root.width
+
+ font.pointSize: JamiTheme.titleFontSize
+
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ text: CurrentConversation.description
+ color: "white"
+
+ onEditingFinished: {
+ ConversationsAdapter.updateConversationDescription(LRCInstance.selectedConvUid, this.text)
+ }
+ }
+
+ TabBar {
+ id: tabBar
+
+ currentIndex: 1
+ Layout.preferredWidth: root.width
+
+ FilterTabButton {
+ id: aboutTabButton
+
+ down: tabBar.currentIndex === 0
+ labelText: JamiStrings.about
+ }
+
+ FilterTabButton {
+ id: membersTabButton
+
+ down: tabBar.currentIndex === 1
+ labelText: JamiStrings.members
+ }
+
+ FilterTabButton {
+ id: documentsTabButton
+
+ down: tabBar.currentIndex === 2
+ labelText: JamiStrings.documents
+ }
+ }
+
+
+ Rectangle {
+ Layout.alignment: Qt.AlignCenter
+ Layout.preferredWidth: root.width
+ Layout.preferredHeight: root.height
+ color: JamiTheme.secondaryBackgroundColor
+ }
+ }
+}