Merge pull request 'Redesign my profile widget to match design. It dynamically resizes and' (#277) from dan/ui:04-widgets into master
the build was successful
Details
the build was successful
Details
This commit is contained in:
commit
0a9b2ed6f5
|
@ -108,9 +108,11 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) {
|
|||
if exists && scope == attr.PublicScope {
|
||||
switch path {
|
||||
case constants.Name:
|
||||
uiManager.UpdateContactDisplayName(onion, val)
|
||||
peer.SetContactAttribute(onion, attr.GetPublicScope(constants.Name), val)
|
||||
uiManager.UpdateContactDisplayName(onion)
|
||||
case constants.Picture:
|
||||
uiManager.UpdateContactPicture(onion, val)
|
||||
peer.SetContactAttribute(onion, attr.GetPublicScope(constants.Picture), val)
|
||||
uiManager.UpdateContactPicture(onion)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,8 +68,8 @@ type GrandCentralDispatcher struct {
|
|||
_ func(loading bool) `signal:"SetLoadingState"`
|
||||
|
||||
// profile-area stuff
|
||||
_ func(name, onion, image string) `signal:"UpdateMyProfile"`
|
||||
_ func(status int, str string) `signal:"TorStatus"`
|
||||
_ func(name, onion, image, tag string) `signal:"UpdateMyProfile"`
|
||||
_ func(status int, str string) `signal:"TorStatus"`
|
||||
|
||||
// settings helpers
|
||||
_ func(str string) `signal:"InvokePopup"`
|
||||
|
@ -605,7 +605,8 @@ func (this *GrandCentralDispatcher) loadProfile(onion string) {
|
|||
pic = NewImage(RandomProfileImage(onion), TypeImageDistro)
|
||||
the.Peer.SetAttribute(attr.GetPublicScope(constants.Picture), ImageToString(pic))
|
||||
}
|
||||
this.UpdateMyProfile(the.Peer.GetName(), the.Peer.GetOnion(), getPicturePath(pic))
|
||||
tag, _ := the.Peer.GetAttribute(app.AttributeTag)
|
||||
this.UpdateMyProfile(the.Peer.GetName(), the.Peer.GetOnion(), getPicturePath(pic), tag)
|
||||
|
||||
contacts := the.Peer.GetContacts()
|
||||
for i := range contacts {
|
||||
|
|
|
@ -67,7 +67,7 @@ func getNick(id string) string {
|
|||
return nick
|
||||
} else {
|
||||
nick, exists := the.Peer.GetContactAttribute(id, attr.GetLocalScope(constants.Name))
|
||||
if !exists {
|
||||
if !exists || nick == "" {
|
||||
nick, exists = the.Peer.GetContactAttribute(id, attr.GetPeerScope(constants.Name))
|
||||
if !exists {
|
||||
nick = id
|
||||
|
@ -203,8 +203,8 @@ type Manager interface {
|
|||
|
||||
ReloadProfiles()
|
||||
|
||||
UpdateContactDisplayName(handle string, name string)
|
||||
UpdateContactPicture(handle string, picVal string)
|
||||
UpdateContactDisplayName(handle string)
|
||||
UpdateContactPicture(handle string)
|
||||
UpdateContactStatus(handle string, status int, loading bool)
|
||||
UpdateContactAttribute(handle, key, value string)
|
||||
|
||||
|
@ -304,19 +304,16 @@ func (this *manager) ReloadProfiles() {
|
|||
}
|
||||
|
||||
// UpdateContactDisplayName updates a contact's display name in the contact list and conversations
|
||||
func (this *manager) UpdateContactDisplayName(handle string, name string) {
|
||||
func (this *manager) UpdateContactDisplayName(handle string) {
|
||||
this.gcd.DoIfProfile(this.profile, func() {
|
||||
this.gcd.UpdateContactDisplayName(handle, name)
|
||||
this.gcd.UpdateContactDisplayName(handle, getNick(handle))
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateContactPicture updates a contact's picture in the contact list and conversations
|
||||
func (this *manager) UpdateContactPicture(handle string, picVal string) {
|
||||
func (this *manager) UpdateContactPicture(handle string) {
|
||||
this.gcd.DoIfProfile(this.profile, func() {
|
||||
pic, err := StringToImage(picVal)
|
||||
if err == nil {
|
||||
this.gcd.UpdateContactPicture(handle, getPicturePath(pic))
|
||||
}
|
||||
this.gcd.UpdateContactPicture(handle, getProfilePic(handle))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
1
qml.qrc
1
qml.qrc
|
@ -28,6 +28,7 @@
|
|||
<file>qml/widgets/InplaceEditText.qml</file>
|
||||
<file>qml/widgets/Message.qml</file>
|
||||
<file>qml/widgets/ScalingLabel.qml</file>
|
||||
<file>qml/widgets/EllipsisLabel.qml</file>
|
||||
<file>qml/widgets/MyProfile.qml</file>
|
||||
<file>qml/widgets/ProfileList.qml</file>
|
||||
<file>qml/widgets/RadioButton.qml</file>
|
||||
|
|
|
@ -87,7 +87,7 @@ ApplicationWindow {
|
|||
property alias pane: parentStack.currentIndex
|
||||
|
||||
Rectangle { // Splash pane
|
||||
color: "#FFFFFF"
|
||||
color: Theme.backgroundMainColor
|
||||
//Layout.fillHeight: true
|
||||
//Layout.minimumWidth: Layout.maximumWidth
|
||||
//Layout.minimumHeight: parent.height
|
||||
|
@ -130,7 +130,7 @@ ApplicationWindow {
|
|||
spacing: 0
|
||||
|
||||
Rectangle { // THE LEFT PANE WITH TOOLS AND CONTACTS
|
||||
color: "#D2C0DD"
|
||||
color: Theme.backgroundMainColor
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: Layout.maximumWidth
|
||||
Layout.maximumWidth: theStack.pane == theStack.emptyPane ? parent.width : Theme.sidePaneMinSize
|
||||
|
@ -139,6 +139,7 @@ ApplicationWindow {
|
|||
|
||||
ContactList{
|
||||
anchors.fill: parent
|
||||
dualPane: theStack.pane != theStack.emptyPane || theStack.pane == undefined
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ TextFieldStyle {
|
|||
id: root
|
||||
textColor: "black"
|
||||
font.pointSize: 10 * gcd.themeScale
|
||||
property int width: 100
|
||||
property int width: parent.width
|
||||
|
||||
background: Rectangle {
|
||||
radius: 2
|
||||
|
|
|
@ -7,6 +7,8 @@ import QtQuick.Layouts 1.3
|
|||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property alias dualPane: myprof.dualPane
|
||||
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
@ -16,7 +18,7 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
MyProfile{ // CURRENT PROFILE INFO AND CONTROL BAR
|
||||
MyProfile { // CURRENT PROFILE INFO AND CONTROL BAR
|
||||
id: myprof
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.4
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQuick.Layouts 1.3
|
||||
import CustomQmlTypes 1.0
|
||||
import "../widgets" as Widgets
|
||||
import "../theme"
|
||||
|
||||
Item {
|
||||
//anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
|
||||
property string text
|
||||
|
||||
property alias color: label.color
|
||||
property alias pixelSize: label.font.pixelSize
|
||||
property alias weight: label.font.weight
|
||||
property alias strikeout: label.font.strikeout
|
||||
|
||||
height: textMetric.height
|
||||
width: textMetric.width + 10
|
||||
anchors.leftMargin: 10
|
||||
|
||||
Label {
|
||||
id: label
|
||||
textFormat: Text.PlainText
|
||||
|
||||
elide: Text.ElideRight
|
||||
text: textMetric.text
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: textMetric
|
||||
text: text
|
||||
font: label.font
|
||||
}
|
||||
|
||||
/*onWidthChanged: {
|
||||
setTextResize()
|
||||
}*/
|
||||
|
||||
onTextChanged: {
|
||||
setTextResize()
|
||||
}
|
||||
|
||||
function setTextResize() {
|
||||
textMetric.text = text
|
||||
var i = 2
|
||||
// - 30 for padding
|
||||
while (textMetric.width > parent.width - (30 * gcd.themeScale) && parent.width > 50) {
|
||||
textMetric.text = text.slice(0, text.length - (i * 3)) + "..."
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -45,7 +45,8 @@ Item {
|
|||
Portrait {
|
||||
id: imgProfile
|
||||
anchors.left: parent.left
|
||||
handle: root.from
|
||||
// TODO: currently unused?
|
||||
//handle: root.from
|
||||
visible: !fromMe
|
||||
//showStatus: false
|
||||
//highlight: ima.containsMouse
|
||||
|
|
|
@ -9,224 +9,149 @@ import QtQuick.Controls 1.4
|
|||
|
||||
import "." as Widgets
|
||||
import "../styles"
|
||||
import "../theme"
|
||||
|
||||
ColumnLayout {
|
||||
Item {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
width: parent.width
|
||||
|
||||
height: profile.height + searchAddText.height + 10
|
||||
implicitHeight: profile.height + searchAddText.height + 10
|
||||
|
||||
property string image
|
||||
property string nick
|
||||
property string onion
|
||||
property string tag
|
||||
property bool dualPane: false
|
||||
|
||||
property real logscale: 4 * Math.log10(gcd.themeScale + 1)
|
||||
|
||||
onDualPaneChanged: { realignProfile() }
|
||||
|
||||
function realignProfile() {
|
||||
if (dualPane) {
|
||||
profile.height = 78 * logscale
|
||||
|
||||
portrait.baseWidth = 78 * logscale
|
||||
portrait.height = 78 * logscale
|
||||
|
||||
portrait.anchors.horizontalCenter = undefined
|
||||
portrait.anchors.left = profile.left
|
||||
portrait.anchors.leftMargin = 25 * logscale
|
||||
|
||||
nameRect.anchors.horizontalCenter = undefined
|
||||
nameRect.anchors.left = portrait.right
|
||||
|
||||
nameRect.anchors.top = undefined
|
||||
nameRect.anchors.verticalCenter = portrait.verticalCenter
|
||||
} else {
|
||||
profile.height = (150 * logscale)
|
||||
|
||||
portrait.baseWidth = 100 * logscale
|
||||
portrait.height = 100 * logscale
|
||||
|
||||
portrait.anchors.left = undefined
|
||||
portrait.anchors.leftMargin = undefined
|
||||
portrait.anchors.horizontalCenter = profile.horizontalCenter
|
||||
|
||||
nameRect.anchors.left = undefined
|
||||
nameRect.anchors.horizontalCenter = profile.horizontalCenter
|
||||
|
||||
nameRect.anchors.verticalCenter = undefined
|
||||
nameRect.anchors.top = portrait.bottom
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: { realignProfile() }
|
||||
|
||||
|
||||
Widgets.Button {// BACK BUTTON
|
||||
id: btnBack
|
||||
icon: "solid/arrow-circle-left"
|
||||
anchors.left: parent.left
|
||||
//anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.leftMargin: 2
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 2
|
||||
onClicked: function() {
|
||||
gcd.selectedProfile = "none"
|
||||
gcd.reloadProfileList()
|
||||
parentStack.pane = parentStack.managementPane
|
||||
theStack.pane = theStack.emptyPane
|
||||
}
|
||||
}
|
||||
|
||||
Item{ height: 6 }
|
||||
Rectangle {
|
||||
|
||||
Item { // PROFILE IMAGE
|
||||
id: imgProfile
|
||||
implicitWidth: 96
|
||||
implicitHeight: 96
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
width: parent.width
|
||||
id: profile
|
||||
|
||||
Rectangle { // WHITE CIRCLE BORDER
|
||||
width: 96
|
||||
height: 96
|
||||
color: "#FFFFFF"
|
||||
radius: width / 2
|
||||
Portrait {
|
||||
id: portrait
|
||||
|
||||
Image { // ACTUAL IMAGE
|
||||
id: imgProfileImg
|
||||
source: gcd.assetPath + root.image
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectFit
|
||||
visible: false
|
||||
}
|
||||
source: root.image
|
||||
|
||||
Image { // INNER CIRCLE MASK
|
||||
id: mask
|
||||
fillMode: Image.PreserveAspectFit
|
||||
visible: false
|
||||
source: "qrc:/qml/images/extra/clipcircle.png"
|
||||
}
|
||||
badgeColor: Theme.portraitProfileBadgeColor
|
||||
portraitBorderColor: Theme.portraitOnlineBorderColor
|
||||
portraitColor: Theme.portraitOnlineBackgroundColor
|
||||
|
||||
OpacityMask { // WE PUT IT ALL TOGETHER ANNND
|
||||
anchors.fill: imgProfileImg
|
||||
source: imgProfileImg
|
||||
maskSource: mask
|
||||
}
|
||||
badgeContent: Image {// Profle Type
|
||||
id: profiletype
|
||||
source: tag == "v1-userPassword" ? gcd.assetPath + "/fontawesome/solid/lock.svg" : gcd.assetPath + "/fontawesome/solid/lock-open.svg"
|
||||
height: Theme.badgeTextSize * gcd.themeScale
|
||||
width: height
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: nameRect
|
||||
|
||||
height: name.height
|
||||
width: name.width + addBtn.width
|
||||
|
||||
EllipsisLabel {
|
||||
id: name
|
||||
|
||||
anchors.right: undefined
|
||||
anchors.left: undefined
|
||||
|
||||
color: Theme.portraitOnlineTextColor
|
||||
pixelSize: Theme.usernameSize * gcd.themeScale
|
||||
weight: Font.Bold
|
||||
text: nick
|
||||
}
|
||||
|
||||
Widgets.Button { // Add Button
|
||||
id: addBtn
|
||||
|
||||
anchors.left: name.right //name.left + name.textWidth
|
||||
anchors.top: name.top
|
||||
|
||||
icon: "solid/plus"
|
||||
|
||||
height: name.height
|
||||
width: height
|
||||
radius: width * 0.3
|
||||
onClicked: {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO Remove for new global topbar
|
||||
Widgets.Button {// BACK BUTTON
|
||||
id: btnBack
|
||||
icon: "solid/arrow-circle-left"
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 2
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 2
|
||||
onClicked: function() {
|
||||
gcd.selectedProfile = "none"
|
||||
gcd.reloadProfileList()
|
||||
parentStack.pane = parentStack.managementPane
|
||||
theStack.pane = theStack.emptyPane
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rectangle { // TOR STATUS INDICATOR
|
||||
color: "#FFFFFF"
|
||||
width: 12
|
||||
height: 12
|
||||
radius: 3
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 8
|
||||
|
||||
|
||||
Rectangle { //0: no tor, 1: progress 0%, 2: progress 1-99%, 3: DONE
|
||||
id: rectTorStatus
|
||||
color: code == 3 ? "green": code == 2 ? "yellow" : code == 1 ? "orange" : "red"
|
||||
width: 8
|
||||
height: 8
|
||||
radius: 2
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 2
|
||||
|
||||
property int code
|
||||
property string message
|
||||
property bool hovered
|
||||
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
|
||||
onEntered: rectTorStatus.hovered = true
|
||||
|
||||
onExited: rectTorStatus.hovered = false
|
||||
}
|
||||
|
||||
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.delay: 400
|
||||
ToolTip.timeout: 5000
|
||||
ToolTip.text: message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InplaceEditText { // USER NICKNAME
|
||||
id: lblNick
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Layout.minimumWidth: parent.width
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
onUpdated: {
|
||||
gcd.updateNick(onion, lblNick.text)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Text {
|
||||
id: txtNick
|
||||
fontSizeMode: Text.HorizontalFit
|
||||
minimumPixelSize: 10
|
||||
font.pixelSize: 20
|
||||
width: 195
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: cbNick.editText
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
parent.visible = false
|
||||
cbNick.visible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox { // USER NICKNAME
|
||||
id: cbNick
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
popup.font.pixelSize: 12
|
||||
width: 200
|
||||
font.pixelSize: 20
|
||||
model: ["erinn", "erinn (open privacy)", "supergirl", "add new profile..."]
|
||||
visible: false
|
||||
|
||||
onCurrentTextChanged: {
|
||||
visible = false
|
||||
txtNick.visible = true
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Text { // ONION ADDRESS
|
||||
id: lblOnion
|
||||
fontSizeMode: Text.HorizontalFit
|
||||
minimumPointSize: 2
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: onion
|
||||
}
|
||||
|
||||
Row { // TOOLS FOR EDITING PROFILE
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: gcd.themeScale * 2
|
||||
|
||||
|
||||
TextEdit { // USED TO POWER THE COPY/PASTE BUTTON
|
||||
id: txtHidden
|
||||
visible: false
|
||||
}
|
||||
|
||||
Widgets.Button { // COPY ONION ADDRESS BUTTON
|
||||
icon: "regular/clipboard"
|
||||
//: Button for copying profile onion address to clipboard
|
||||
text: qsTr("copy-btn")
|
||||
|
||||
onClicked: {
|
||||
//: Copied to clipboard
|
||||
gcd.popup(qsTr("copied-clipboard-notification"))
|
||||
txtHidden.text = nick.replace(" ", "~") + "~" + onion
|
||||
txtHidden.selectAll()
|
||||
txtHidden.copy()
|
||||
}
|
||||
}
|
||||
|
||||
Widgets.Button { // SETTINGS BUTTON
|
||||
icon: "solid/cog"
|
||||
|
||||
onClicked: theStack.pane = theStack.settingsPane
|
||||
}
|
||||
|
||||
Widgets.Button { // SIGN OUT BUTTON
|
||||
icon: "solid/sign-out-alt"
|
||||
|
||||
onClicked: {
|
||||
gcd.popup("not yet implemented, sorry :(")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing: gcd.themeScale * 2
|
||||
|
||||
|
||||
Widgets.Button { // CREATE GROUP BUTTON
|
||||
icon: "regular/clipboard"
|
||||
//: create new group button
|
||||
text: qsTr("new-group-btn")
|
||||
|
||||
onClicked: theStack.pane = theStack.addGroupPane
|
||||
}
|
||||
}
|
||||
|
||||
TextField {
|
||||
TextField {
|
||||
id: searchAddText
|
||||
anchors.top: profile.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
style: CwtchTextFieldStyle{ width: 400 }
|
||||
|
||||
style: CwtchTextFieldStyle{ }
|
||||
width: parent.width - 30
|
||||
//: ex: "... paste an address here to add a contact ..."
|
||||
placeholderText: qsTr("paste-address-to-add-contact")
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
|
@ -242,16 +167,16 @@ ColumnLayout {
|
|||
Connections {
|
||||
target: gcd
|
||||
|
||||
onUpdateMyProfile: function(_nick, _onion, _image) {
|
||||
onUpdateMyProfile: function(_nick, _onion, _image, _tag) {
|
||||
nick = _nick
|
||||
lblNick.text = _nick
|
||||
onion = _onion
|
||||
image = _image
|
||||
tag = _tag
|
||||
}
|
||||
|
||||
onTorStatus: function(code, str) {
|
||||
/*onTorStatus: function(code, str) {
|
||||
rectTorStatus.code = code
|
||||
rectTorStatus.message = str
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,20 +11,23 @@ Item {
|
|||
implicitWidth: baseWidth
|
||||
implicitHeight: baseWidth
|
||||
|
||||
property string handle
|
||||
property string source
|
||||
property alias badgeColor: badge.color
|
||||
|
||||
property real logscale: 4 * Math.log10(gcd.themeScale + 1)
|
||||
property int baseWidth: parent.height
|
||||
property int baseWidth: 78 * logscale
|
||||
height: 78 * logscale
|
||||
|
||||
property alias portraitBorderColor: mainImage.color
|
||||
property alias portraitColor: imageInner.color
|
||||
property alias badgeVisible: badge.visible
|
||||
property alias badgeContent: badge.content
|
||||
|
||||
|
||||
Rectangle {
|
||||
id: mainImage
|
||||
//anchors.leftMargin: baseWidth * 0.1
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: baseWidth * 0.8
|
||||
height: width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
|
|
@ -18,7 +18,7 @@ Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
|
|||
implicitHeight: 78 * logscale + 3 //height
|
||||
|
||||
property real logscale: 4 * Math.log10(gcd.themeScale + 1)
|
||||
property string displayName //: nameTxtmetric.text
|
||||
property string displayName
|
||||
property alias image: portrait.source
|
||||
property string handle
|
||||
property bool isActive
|
||||
|
@ -30,9 +30,12 @@ Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
|
|||
property alias portraitColor: portrait.portraitColor
|
||||
property alias nameColor: cn.color
|
||||
property alias onionColor: onion.color
|
||||
property alias onionVisible: onion.visible
|
||||
property alias badgeVisible: portrait.badgeVisible
|
||||
property alias badgeContent: portrait.badgeContent
|
||||
property alias hoverEnabled: buttonMA.hoverEnabled
|
||||
|
||||
property alias content: extraMeta.children
|
||||
|
||||
// TODO: should be in ContactRow
|
||||
property bool blocked
|
||||
|
@ -55,64 +58,42 @@ Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
|
|||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: portraitMeta
|
||||
|
||||
anchors.left: portrait.right
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 4 * logscale
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Label { // CONTACT NAME
|
||||
spacing: 2 * gcd.themeScale
|
||||
|
||||
|
||||
EllipsisLabel { // CONTACT NAME
|
||||
id: cn
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
//wrapMode: Text.WordWrap
|
||||
font.pixelSize: Theme.usernameSize * gcd.themeScale
|
||||
font.weight: Font.Bold
|
||||
font.strikeout: blocked
|
||||
elide: Text.ElideRight
|
||||
text: nameTxtmetric.text
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: nameTxtmetric
|
||||
pixelSize: Theme.usernameSize * gcd.themeScale
|
||||
weight: Font.Bold
|
||||
strikeout: blocked
|
||||
text: displayName
|
||||
font: cn.font
|
||||
}
|
||||
|
||||
|
||||
Label { // Onion
|
||||
EllipsisLabel { // Onion
|
||||
id: onion
|
||||
text: onionTxtmetric.text
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
font.pixelSize: Theme.secondaryTextSize * gcd.themeScale
|
||||
font.strikeout: blocked
|
||||
textFormat: Text.PlainText
|
||||
elide: Text.ElideRight
|
||||
text: handle
|
||||
pixelSize: Theme.secondaryTextSize * gcd.themeScale
|
||||
strikeout: blocked
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: onionTxtmetric
|
||||
text: handle
|
||||
font: onion.font
|
||||
}
|
||||
onWidthChanged: {
|
||||
cn.setTextResize()
|
||||
onion.setTextResize()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onWidthChanged: {
|
||||
nameTxtmetric.text = displayName
|
||||
onionTxtmetric.text = handle
|
||||
var i = 2
|
||||
var maxWidth = Math.max(200, width - portrait.width - (50 * logscale))
|
||||
|
||||
while (nameTxtmetric.width > maxWidth) {
|
||||
nameTxtmetric.text = displayName.slice(0, displayName.length - (i * 3)) + "..."
|
||||
i++
|
||||
}
|
||||
i = 2
|
||||
while (onionTxtmetric.width > maxWidth) {
|
||||
onionTxtmetric.text = handle.slice(0, handle.length - (i * 3)) + "..."
|
||||
i++
|
||||
}
|
||||
Column {
|
||||
id: extraMeta
|
||||
anchors.left: portraitMeta.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,7 +128,7 @@ Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
|
|||
|
||||
onUpdateContactDisplayName: function(_handle, _displayName) {
|
||||
if (handle == _handle) {
|
||||
displayName = _displayName + (_blocked == true ? " (blocked)" : "")
|
||||
displayName = _displayName + (blocked == true ? " (blocked)" : "")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Reference in New Issue