294 lines
8.9 KiB
QML
294 lines
8.9 KiB
QML
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
|
|
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
|
|
|
|
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
|
|
|
|
property int imageSize: ProfileHeader.ImageSize.Compact
|
|
property bool displayNameVisible: true
|
|
property bool displayNamePlusIconsVisible: false
|
|
property bool pubkeyVisible: true
|
|
property alias emojiHash: emojiHash.emojiHash
|
|
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
|
|
|
|
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
|
|
}
|
|
|
|
Item {
|
|
Layout.alignment: Qt.AlignHCenter
|
|
implicitWidth: userImage.width
|
|
implicitHeight: userImage.height
|
|
|
|
UserImage {
|
|
id: userImage
|
|
|
|
objectName: "ProfileHeader_userImage"
|
|
name: root.displayName
|
|
colorHash: root.colorHash
|
|
colorId: root.colorId
|
|
image: root.previewIcon
|
|
interactive: false
|
|
imageWidth: d.getSize(36, 64, 170)
|
|
imageHeight: imageWidth
|
|
ensVerified: root.userIsEnsVerified
|
|
loading: root.loading
|
|
onlineStatus: root.onlineStatus
|
|
isBridgedAccount: root.isBridgedAccount
|
|
}
|
|
|
|
StatusRoundButton {
|
|
id: editButton
|
|
visible: root.editImageButtonVisible
|
|
anchors.top: userImage.top
|
|
anchors.right: userImage.right
|
|
anchors.rightMargin: Math.round(userImage.width / 10)
|
|
|
|
width: d.getSize(10, 24, 40)
|
|
height: width
|
|
|
|
type: StatusRoundButton.Type.Secondary
|
|
icon.name: "edit_pencil"
|
|
icon.width: d.getSize(8, 12, 24)
|
|
icon.height: d.getSize(8, 12, 24)
|
|
|
|
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
|
|
}
|
|
}
|
|
|
|
StatusContactVerificationIcons {
|
|
id: verificationIcons
|
|
visible: !root.isCurrentUser && !root.isBridgedAccount
|
|
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 = ""
|
|
}
|
|
}
|
|
}
|
|
}
|