-
Sébastien Blin authored
Change-Id: I3cd9bf1c020a8c7a265e301ea021faedfd619295
Sébastien Blin authoredChange-Id: I3cd9bf1c020a8c7a265e301ea021faedfd619295
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
SwarmDetailsPanel.qml 29.81 KiB
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* 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 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
property alias tabBarIndex: tabBar.currentIndex
property int tabBarItemsLength: tabBar.contentChildren.length
color: CurrentConversation.color
property var isAdmin: UtilsAdapter.getParticipantRole(CurrentAccount.id,
CurrentConversation.id,
CurrentAccount.uri) === Member.Role.ADMIN
|| CurrentConversation.isCoreDialog
property string textColor: UtilsAdapter.luma(root.color) ?
JamiTheme.chatviewTextColorLight :
JamiTheme.chatviewTextColorDark
ColumnLayout {
id: swarmProfileDetails
anchors.fill: parent
spacing: 0
ColumnLayout {
id: header
Layout.topMargin: JamiTheme.swarmDetailsPageTopMargin
Layout.fillWidth: true
spacing: JamiTheme.preferredMarginSize
RowLayout {
spacing: 15
Layout.leftMargin: 15
PhotoboothView {
id: currentAccountAvatar
readOnly: !root.isAdmin
width: avatarSize
height: avatarSize
Layout.alignment: Qt.AlignHCenter
newItem: true
imageId: LRCInstance.selectedConvUid
avatarSize: JamiTheme.smartListAvatarSize * 3/2
}
ColumnLayout {
signal accepted
ModalTextEdit {
id: titleLine
TextMetrics {
id: titleLineTextSize
text: CurrentConversation.title
elide: Text.ElideRight
elideWidth: titleLine.width
font.pixelSize: JamiTheme.materialLineEditPixelSize
}
maxCharacters: JamiTheme.maximumCharacters
isSwarmDetail: true
readOnly: !isAdmin
Layout.minimumHeight: JamiTheme.preferredFieldHeight
Layout.preferredWidth: Math.min(217,swarmProfileDetails.width - currentAccountAvatar.width - 30 - JamiTheme.settingsMarginSize)
staticText: CurrentConversation.title
elidedText: titleLineTextSize.elidedText
textColor: root.textColor
prefixIconColor: root.textColor
onAccepted: {
ConversationsAdapter.updateConversationTitle(
LRCInstance.selectedConvUid, dynamicText)
}
editMode: false
isPersistent: false
onActiveFocusChanged: {
if (!activeFocus) {
ConversationsAdapter.updateConversationTitle(LRCInstance.selectedConvUid, dynamicText)
}
titleLine.editMode = activeFocus
}
infoTipLineText: CurrentConversation.isCoreDialog? JamiStrings.contactName : JamiStrings.swarmName
}
ModalTextEdit {
id: descriptionLineButton
TextMetrics {
id: descriptionLineButtonTextSize
text: CurrentConversation.description
elide: Text.ElideRight
elideWidth: descriptionLineButton.width
font.pixelSize: JamiTheme.materialLineEditPixelSize
}
maxCharacters: JamiTheme.maximumCharacters
isSwarmDetail: true
readOnly: !isAdmin || CurrentConversation.isCoreDialog
Layout.minimumHeight: JamiTheme.preferredFieldHeight
Layout.preferredWidth: Math.min(217,swarmProfileDetails.width - currentAccountAvatar.width - 30 - JamiTheme.settingsMarginSize)
staticText: CurrentConversation.description
placeholderText: JamiStrings.addADescription
elidedText: descriptionLineButtonTextSize.elidedText
textColor: root.textColor
prefixIconColor: root.textColor
onAccepted: ConversationsAdapter.updateConversationDescription(
LRCInstance.selectedConvUid, dynamicText)
editMode: false
isPersistent: false
onActiveFocusChanged: {
if (!activeFocus) {
ConversationsAdapter.updateConversationDescription(
LRCInstance.selectedConvUid, dynamicText)
}
descriptionLineButton.editMode = activeFocus
}
infoTipLineText: JamiStrings.addADescription
}
}
}
TabBar {
id: tabBar
currentIndex: 0
Layout.preferredWidth: root.width
Layout.preferredHeight: settingsTabButton.height
property string currentItemName: itemAt(currentIndex).objectName
component DetailsTabButton: FilterTabButton {
backgroundColor: CurrentConversation.color
hoverColor: CurrentConversation.color
borderWidth: 4
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
Layout.fillWidth: true
down: tabBar.currentIndex === TabBar.index
}
function addRemoveButtons() {
if (CurrentConversation.isCoreDialog) {
if (tabBar.contentChildren.length === 3)
tabBar.removeItem(tabBar.itemAt(1))
} else {
if (tabBar.contentChildren.length === 2) {
const obj = membersTabButtonComp.createObject(tabBar)
tabBar.insertItem(1, obj)
}
}
}
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: documentsTabButton
objectName: "documents"
labelText: JamiStrings.documents
}
DetailsTabButton {
id: settingsTabButton
objectName: "settings"
labelText: JamiStrings.settings
}
}
}
Component {
id: colorDialogComp
ColorDialog {
id: colorDialog
title: JamiStrings.chooseAColor
onAccepted: {
CurrentConversation.setPreference("color", colorDialog.color)
this.destroy()
}
onRejected: this.destroy()
}
}
Rectangle {
id: details
Layout.fillWidth: true
Layout.preferredHeight: root.height - header.height - 2*JamiTheme.preferredMarginSize
color: JamiTheme.secondaryBackgroundColor
JamiFlickable {
id: settingsScrollView
property ScrollBar vScrollBar: ScrollBar.vertical
anchors.fill: parent
contentHeight: aboutSwarm.height + JamiTheme.preferredMarginSize
ColumnLayout {
id: aboutSwarm
anchors.left: parent.left
anchors.right: parent.right
visible: tabBar.currentItemName === "settings"
Layout.alignment: Qt.AlignTop
spacing: 0
SwarmDetailsItem {
id: firstParameter
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.settingsFontSize + 2 * JamiTheme.preferredMarginSize + 4
ToggleSwitch {
id: ignoreSwarm
anchors.fill: parent
anchors.leftMargin: JamiTheme.preferredMarginSize
anchors.rightMargin: JamiTheme.settingsMarginSize
checked: CurrentConversation.ignoreNotifications
labelText: JamiStrings.muteConversation
tooltipText: JamiStrings.ignoreNotificationsTooltip
onSwitchToggled: {
CurrentConversation.setPreference("ignoreNotifications", checked ? "true" : "false")
}
}
}
SwarmDetailsItem {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.settingsFontSize + 2 * JamiTheme.preferredMarginSize + 4
Text {
anchors.left: parent.left
anchors.top: parent.top
anchors.margins: JamiTheme.preferredMarginSize
text: JamiStrings.leaveConversation
font.pixelSize: JamiTheme.participantSwarmDetailFontSize
font.kerning: true
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
color: JamiTheme.textColor
}
TapHandler {
target: parent
enabled: parent.visible
onTapped: function onTapped(eventPoint) {
var dlg = viewCoordinator.presentDialog(
appWindow,
"commoncomponents/ConfirmDialog.qml",
{
title: JamiStrings.confirmAction,
textLabel: JamiStrings.confirmRmConversation,
confirmLabel: JamiStrings.optionRemove
})
dlg.accepted.connect(function() {
MessagesAdapter.removeConversation(LRCInstance.selectedConvUid)
})
}
}
}
SwarmDetailsItem {
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.settingsFontSize + 2 * JamiTheme.preferredMarginSize + 4
visible: CurrentAccount.type !== Profile.Type.SIP // TODO for SIP save in VCard
RowLayout {
anchors.fill: parent
anchors.leftMargin: JamiTheme.preferredMarginSize
anchors.rightMargin: JamiTheme.preferredMarginSize
Text {
Layout.fillWidth: true
Layout.preferredHeight: 30
Layout.rightMargin: JamiTheme.preferredMarginSize
text: JamiStrings.chooseAColor
font.pixelSize: JamiTheme.participantSwarmDetailFontSize
font.kerning: true
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
color: JamiTheme.textColor
}
Rectangle {
id: chooseAColorBtn
Layout.alignment: Qt.AlignRight
width: JamiTheme.aboutBtnSize
height: JamiTheme.aboutBtnSize
radius: JamiTheme.aboutBtnSize / 2
color: CurrentConversation.color
}
}
TapHandler {
target: parent
enabled: parent.visible
onTapped: function onTapped(eventPoint) {
colorDialogComp.createObject(appWindow).open()
}
}
}
SwarmDetailsItem {
id: settingsSwarmItem
Layout.fillWidth: true
Layout.preferredHeight: JamiTheme.settingsFontSize + 2 * JamiTheme.preferredMarginSize + 4
visible: !CurrentConversation.isCoreDialog
RowLayout {
anchors.fill: parent
anchors.leftMargin: JamiTheme.preferredMarginSize
anchors.rightMargin: JamiTheme.preferredMarginSize
Text {
id: settingsSwarmText
Layout.fillWidth: true
Layout.preferredHeight: 30
Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.maximumWidth: settingsSwarmItem.width / 2
text: JamiStrings.defaultCallHost
font.pixelSize: JamiTheme.participantSwarmDetailFontSize
font.kerning: true
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
color: JamiTheme.textColor
}
RowLayout {
id: swarmRdvPref
spacing: 10
Layout.alignment: Qt.AlignRight
Layout.fillWidth: true
Connections {
target: CurrentConversation
function onRdvAccountChanged() {
// This avoid incorrect avatar by always modifying the mode before the imageId
avatar.mode = CurrentConversation.rdvAccount === CurrentAccount.uri ? Avatar.Mode.Account : Avatar.Mode.Contact
avatar.imageId = CurrentConversation.rdvAccount === CurrentAccount.uri ? CurrentAccount.id : CurrentConversation.rdvAccount
}
}
Avatar {
id: avatar
width: JamiTheme.contactMessageAvatarSize
height: JamiTheme.contactMessageAvatarSize
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.topMargin: JamiTheme.preferredMarginSize / 2
visible: CurrentConversation.rdvAccount !== ""
imageId: ""
showPresenceIndicator: false
mode: Avatar.Mode.Account
}
ColumnLayout {
spacing: 0
Layout.alignment: Qt.AlignVCenter
Layout.fillWidth: true
ElidedTextLabel {
id: bestName
eText: {
if (CurrentConversation.rdvAccount === "")
return JamiStrings.none
else if (CurrentConversation.rdvAccount === CurrentAccount.uri)
return CurrentAccount.bestName
else
return UtilsAdapter.getBestNameForUri(CurrentAccount.id, CurrentConversation.rdvAccount)
}
maxWidth: settingsSwarmItem.width / 2 - JamiTheme.contactMessageAvatarSize
font.pointSize: eText === JamiStrings.none ? JamiTheme.settingsFontSize : JamiTheme.smartlistItemInfoFontSize
font.weight: eText === JamiStrings.none ? Font.Medium : Font.Normal
color: JamiTheme.primaryForegroundColor
font.kerning: true
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
ElidedTextLabel {
id: deviceId
eText: CurrentConversation.rdvDevice === "" ? JamiStrings.none : CurrentConversation.rdvDevice
visible: CurrentConversation.rdvDevice !== ""
maxWidth: settingsSwarmItem.width / 2 - JamiTheme.contactMessageAvatarSize
font.pointSize: JamiTheme.settingsFontSize
color: JamiTheme.textColorHovered
font.kerning: true
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
}
}
}
TapHandler {
target: parent
enabled: parent.visible && root.isAdmin
onTapped: function onTapped(eventPoint) {
viewCoordinator.presentDialog(
appWindow,
"mainview/components/DevicesListPopup.qml")
}
}
}
RowLayout {
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.preferredHeight: JamiTheme.settingsFontSize + 2 * JamiTheme.preferredMarginSize + 4
visible: CurrentAccount.type !== Profile.Type.SIP
Text {
Layout.fillWidth: true
Layout.preferredHeight: 30
Layout.rightMargin: JamiTheme.preferredMarginSize
text: JamiStrings.typeOfSwarm
font.pixelSize: JamiTheme.participantSwarmDetailFontSize
font.kerning: true
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
color: JamiTheme.textColor
}
Text {
id: typeOfSwarmLabel
Layout.alignment: Qt.AlignRight
Layout.rightMargin: JamiTheme.preferredMarginSize
color: JamiTheme.textColor
font.pixelSize: JamiTheme.participantSwarmDetailFontSize
font.weight: Font.Medium
text: CurrentConversation.modeString
}
}
RowLayout {
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.preferredHeight: JamiTheme.settingsFontSize + 2 * JamiTheme.preferredMarginSize + 4
Layout.maximumWidth: parent.width
visible: LRCInstance.debugMode()
Text {
id: idLabel
Layout.preferredHeight: 30
Layout.rightMargin: JamiTheme.preferredMarginSize
Layout.maximumWidth: parent.width / 2
text: JamiStrings.identifier
font.pixelSize: JamiTheme.participantSwarmDetailFontSize
font.kerning: true
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
color: JamiTheme.textColor
}
Text {
Layout.alignment: Qt.AlignRight
Layout.rightMargin: JamiTheme.settingsMarginSize
Layout.maximumWidth: parent.width / 2
color: JamiTheme.textColor
font.pixelSize: JamiTheme.participantSwarmDetailFontSize
text: CurrentConversation.id
elide: Text.ElideRight
}
}
}
}
JamiListView {
id: members
anchors.topMargin: JamiTheme.preferredMarginSize
anchors.bottomMargin: JamiTheme.preferredMarginSize
anchors.fill: parent
visible: tabBar.currentItemName === "members"
SwarmParticipantContextMenu {
id: contextMenu
role: UtilsAdapter.getParticipantRole(CurrentAccount.id, CurrentConversation.id, CurrentAccount.uri)
function openMenuAt(x, y, participantUri) {
contextMenu.x = x
contextMenu.y = y
contextMenu.conversationId = CurrentConversation.id
contextMenu.participantUri = participantUri
openMenu()
}
}
model: CurrentConversationMembers
delegate: ItemDelegate {
id: member
width: members.width
height: JamiTheme.smartListItemHeight
background: Rectangle {
anchors.fill: parent
color: {
if (member.hovered || nameTextEditHover.hovered)
return JamiTheme.smartListHoveredColor
else
return "transparent"
}
}
MouseArea {
id: memberMouseArea
anchors.fill: parent
enabled: MemberUri !== CurrentAccount.uri
acceptedButtons: Qt.RightButton
onClicked: function (mouse) {
var position = mapToItem(members, mouse.x, mouse.y)
contextMenu.openMenuAt(position.x, position.y, MemberUri)
}
}
RowLayout {
spacing: 10
anchors.fill: parent
anchors.rightMargin: JamiTheme.preferredMarginSize
Avatar {
width: JamiTheme.smartListAvatarSize
height: JamiTheme.smartListAvatarSize
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.topMargin: JamiTheme.preferredMarginSize / 2
z: -index
opacity: (MemberRole === Member.Role.INVITED || MemberRole === Member.Role.BANNED)? 0.5 : 1
imageId: CurrentAccount.uri === MemberUri ? CurrentAccount.id : MemberUri
showPresenceIndicator: UtilsAdapter.getContactPresence(CurrentAccount.id, MemberUri)
mode: CurrentAccount.uri === MemberUri ? Avatar.Mode.Account : Avatar.Mode.Contact
}
ElidedTextLabel {
id: nameTextEdit
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.topMargin: JamiTheme.preferredMarginSize / 2
Layout.fillWidth: true
eText: UtilsAdapter.getContactBestName(CurrentAccount.id, MemberUri)
maxWidth: width
font.pointSize: JamiTheme.settingsFontSize
color: JamiTheme.primaryForegroundColor
opacity: (MemberRole === Member.Role.INVITED || MemberRole === Member.Role.BANNED)? 0.5 : 1
font.kerning: true
verticalAlignment: Text.AlignVCenter
HoverHandler {
id: nameTextEditHover
}
}
ElidedTextLabel {
id: roleLabel
Layout.preferredHeight: JamiTheme.preferredFieldHeight
Layout.topMargin: JamiTheme.preferredMarginSize / 2
eText: {
if (MemberRole === Member.Role.ADMIN)
return JamiStrings.administrator
if (MemberRole === Member.Role.INVITED)
return JamiStrings.invited
if (MemberRole === Member.Role.BANNED)
return JamiStrings.banned
return ""
}
maxWidth: JamiTheme.preferredFieldWidth
font.pointSize: JamiTheme.settingsFontSize
color: JamiTheme.textColorHovered
opacity: (MemberRole === Member.Role.INVITED || MemberRole === Member.Role.BANNED)? 0.5 : 1
font.kerning: true
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
}
}
}
}
DocumentsScrollview {
id: documents
visible: tabBar.currentItemName === "documents"
anchors.fill: parent
}
}
}
}