status-desktop/ui/app/AppLayouts/Chat/panels/UserListPanel.qml

142 lines
4.8 KiB
QML

import QtQuick 2.13
import QtQuick.Controls 2.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import shared 1.0
import shared.panels 1.0
import shared.status 1.0
import utils 1.0
import "../controls"
import SortFilterProxyModel 0.2
Item {
id: root
anchors.fill: parent
// Important:
// Each chat/channel has its own ChatContentModule and each ChatContentModule has a single usersModule
// usersModule on the backend contains everything needed for this component
property var usersModule
property var messageContextMenu
property string label
property var rootStore
StatusBaseText {
id: titleText
anchors.top: parent.top
anchors.topMargin: Style.current.padding
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
opacity: (root.width > 58) ? 1.0 : 0.0
visible: (opacity > 0.1)
font.pixelSize: Style.current.primaryTextFontSize
font.weight: Font.Medium
color: Theme.palette.directColor1
text: root.label
}
StatusListView {
id: userListView
objectName: "userListPanel"
clip: true
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded
}
anchors {
top: titleText.bottom
topMargin: Style.current.padding
left: parent.left
right: parent.right
bottom: parent.bottom
bottomMargin: Style.current.bigPadding
}
model: SortFilterProxyModel {
sourceModel: usersModule.model
sorters: [
RoleSorter {
roleName: "onlineStatus"
sortOrder: Qt.DescendingOrder
},
StringSorter {
roleName: "displayName"
caseSensitivity: Qt.CaseInsensitive
}
]
}
section.property: "onlineStatus"
section.delegate: (root.width > 58) ? sectionDelegateComponent : null
delegate: StatusMemberListItem {
anchors.left: parent.left
anchors.leftMargin: 8
anchors.right: parent.right
anchors.rightMargin: 8
nickName: model.localNickname
userName: model.displayName
pubKey: Utils.getCompressedPk(model.pubKey)
isContact: model.isContact
isVerified: model.isVerified
isUntrustworthy: model.isUntrustworthy
isAdmin: model.isAdmin
image.source: {
if ((!model.isContact &&
Global.privacyModuleInst.profilePicturesVisibility !==
Constants.profilePicturesVisibility.everyone)) {
return "";
}
return model.icon;
}
image.isIdenticon: false
status: model.onlineStatus
icon.color: Theme.palette.userCustomizationColors[Utils.colorIdForPubkey(model.pubKey)] // FIXME: use model.colorId
ringSettings.ringSpecModel: Utils.getColorHashAsJson(model.pubKey) // FIXME: use model.colorHash
onClicked: {
if (mouse.button === Qt.RightButton) {
// Set parent, X & Y positions for the messageContextMenu
messageContextMenu.parent = this
messageContextMenu.setXPosition = function() { return 0; }
messageContextMenu.setYPosition = function() { return mouse.y + (Style.current.halfPadding/2); }
messageContextMenu.isProfile = true
messageContextMenu.myPublicKey = userProfile.pubKey
messageContextMenu.selectedUserPublicKey = model.pubKey
messageContextMenu.selectedUserDisplayName = model.displayName
messageContextMenu.selectedUserIcon = image.source
messageContextMenu.popup()
} else if (mouse.button === Qt.LeftButton && !!messageContextMenu) {
Global.openProfilePopup(model.pubKey);
}
}
}
}
Component {
id: sectionDelegateComponent
Item {
width: parent.width
height: 24
StyledText {
anchors.fill: parent
anchors.leftMargin: Style.current.padding
verticalAlignment: Text.AlignVCenter
font.pixelSize: Style.current.additionalTextSize
color: Theme.palette.baseColor1
text: {
switch(parseInt(section)) {
case Constants.onlineStatus.online:
return qsTr("Online")
default:
return qsTr("Inactive")
}
}
}
}
}
}