status-desktop/ui/imports/shared/controls/chat/ProfileHeader.qml

294 lines
8.9 KiB
QML
Raw Normal View History

import QtQuick 2.15
import QtQuick.Layouts 1.15
import utils 1.0
import shared.panels 1.0
import shared.controls 1.0
import StatusQ 0.1
2022-06-22 12:16:21 +00:00
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import StatusQ.Core.Theme 0.1
Item {
id: root
2022-06-22 12:16:21 +00:00
enum ImageSize {
Compact,
Middle,
Big
}
property string displayName
property string compressedPubKey
property string icon
property url previewIcon: icon
property int trustStatus
property int onlineStatus: Constants.onlineStatus.unknown
property bool isContact: false
property bool isBlocked
property bool isCurrentUser
property bool userIsEnsVerified
property rect cropRect
property var colorHash: []
property int colorId
2022-06-22 12:16:21 +00:00
property int imageSize: ProfileHeader.ImageSize.Compact
property bool displayNameVisible: true
property bool displayNamePlusIconsVisible: false
property bool pubkeyVisible: true
property alias emojiHash: emojiHash.emojiHash
2022-06-22 12:16:21 +00:00
property bool emojiHashVisible: true
property bool editImageButtonVisible: false
property bool editButtonVisible: displayNamePlusIconsVisible
property bool loading: false
readonly property bool compact: root.imageSize === ProfileHeader.ImageSize.Compact
property bool isBridgedAccount: false
signal clicked()
signal editClicked()
Binding on previewIcon {
value: icon
}
implicitWidth: contentContainer.implicitWidth
implicitHeight: contentContainer.implicitHeight
2022-06-22 12:16:21 +00:00
QtObject {
id: d
function getSize(compact, normal, big) {
switch(root.imageSize) {
case ProfileHeader.ImageSize.Compact: return compact;
case ProfileHeader.ImageSize.Middle: return normal;
case ProfileHeader.ImageSize.Big: return big;
}
}
}
Item {
id: tmpCroppedImageHelper
visible: false
Image {
id: tmpImage
mipmap: true
cache: false
}
property var keepGrabResultAlive;
function setCroppedTmpIcon(source, x, y, width, height) {
tmpCroppedImageHelper.width = width
tmpCroppedImageHelper.height = height
tmpImage.x = -x
tmpImage.y = -y
tmpImage.source = source
tmpCroppedImageHelper.grabToImage(result => {
keepGrabResultAlive = result
root.previewIcon = result.url
tmpImage.source = ""
})
}
}
ColumnLayout {
id: contentContainer
spacing: root.compact ? 4 : 12
anchors {
left: parent.left
right: parent.right
leftMargin: Theme.smallPadding
rightMargin: Theme.smallPadding
}
2022-06-22 12:16:21 +00:00
Item {
Layout.alignment: Qt.AlignHCenter
2022-06-22 12:16:21 +00:00
implicitWidth: userImage.width
implicitHeight: userImage.height
UserImage {
id: userImage
objectName: "ProfileHeader_userImage"
2022-06-22 12:16:21 +00:00
name: root.displayName
colorHash: root.colorHash
colorId: root.colorId
image: root.previewIcon
2022-06-22 12:16:21 +00:00
interactive: false
imageWidth: d.getSize(36, 64, 170)
2022-06-22 12:16:21 +00:00
imageHeight: imageWidth
ensVerified: root.userIsEnsVerified
loading: root.loading
onlineStatus: root.onlineStatus
isBridgedAccount: root.isBridgedAccount
2022-06-22 12:16:21 +00:00
}
StatusRoundButton {
id: editButton
2022-06-22 12:16:21 +00:00
visible: root.editImageButtonVisible
anchors.top: userImage.top
2022-06-22 12:16:21 +00:00
anchors.right: userImage.right
anchors.rightMargin: Math.round(userImage.width / 10)
2022-06-22 12:16:21 +00:00
width: d.getSize(10, 24, 40)
height: width
2022-06-22 12:16:21 +00:00
type: StatusRoundButton.Type.Secondary
icon.name: "edit_pencil"
icon.width: d.getSize(8, 12, 24)
icon.height: d.getSize(8, 12, 24)
2022-06-22 12:16:21 +00:00
onClicked: {
if (!!root.icon)
Global.openMenu(editImageMenuComponent, this)
else
Global.openChangeProfilePicPopup(tempIcon);
}
function tempIcon(image, aX, aY, bX, bY) {
root.icon = image
root.cropRect = Qt.rect(aX, aY, bX - aX, bY - aY)
tmpCroppedImageHelper.setCroppedTmpIcon(
image, aX, aY, bX - aX, bY - aY)
}
}
}
Item {
Layout.fillWidth: true
implicitHeight: displayNameLabel.implicitHeight
visible: root.displayNameVisible
StyledText {
id: displayNameLabel
width: parent.width
height: parent.height
text: root.displayName
visible: !root.loading
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
maximumLineCount: 3
wrapMode: Text.Wrap
font {
bold: true
pixelSize: 17
}
}
Loader {
anchors.centerIn: parent
height: parent.height
width: 100
visible: root.loading
active: visible
sourceComponent: LoadingComponent {
radius: 4
}
}
}
RowLayout {
spacing: compact ? 4 : Theme.halfPadding
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
visible: root.displayNamePlusIconsVisible
StyledText {
objectName: "ProfileHeader_displayName"
Layout.maximumWidth: root.width - verificationIcons.width - contentContainer.anchors.leftMargin - contentContainer.anchors.rightMargin -
(editButtonLoader.active ? editButtonLoader.item.width : 0)
text: root.displayName
elide: Text.ElideRight
font {
weight: Font.Medium
pixelSize: Theme.primaryTextFontSize
}
}
2022-09-27 21:26:26 +00:00
StatusContactVerificationIcons {
id: verificationIcons
visible: !root.isCurrentUser && !root.isBridgedAccount
2022-09-27 21:26:26 +00:00
isContact: root.isContact
trustIndicator: root.trustStatus
isBlocked: root.isBlocked
}
Loader {
id: editButtonLoader
sourceComponent: SVGImage {
objectName: "ProfileHeader_displayNameEditIcon"
height: compact ? 10 : 16
width: compact ? 10 : 16
source: Theme.svg("edit-message")
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton
onClicked: {
root.editClicked()
}
}
}
active: root.editButtonVisible
visible: active
}
}
StyledText {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
visible: root.pubkeyVisible
text: root.isBridgedAccount ? qsTr("Bridged from Discord") : Utils.getElidedPk(compressedPubKey)
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 13
color: Theme.palette.secondaryText
}
EmojiHash {
id: emojiHash
Layout.alignment: Qt.AlignHCenter
visible: root.emojiHashVisible && !root.isBridgedAccount
compact: root.compact
}
}
Component {
id: editImageMenuComponent
StatusMenu {
onClosed: destroy()
StatusAction {
text: !!root.icon ? qsTr("Select different image") : qsTr("Select image")
assetSettings.name: "image"
onTriggered: Global.openChangeProfilePicPopup(editButton.tempIcon)
}
StatusAction {
text: qsTr("Use a collectible")
assetSettings.name: "nft-profile"
onTriggered: Global.openChangeProfilePicPopup(editButton.tempIcon)
enabled: false // TODO enable this with the profile showcase (#13418)
}
StatusMenuSeparator {}
StatusAction {
text: qsTr("Remove image")
type: StatusAction.Danger
assetSettings.name: "delete"
onTriggered: root.icon = ""
}
}
}
}