diff --git a/go/handlers/peerHandler.go b/go/handlers/peerHandler.go
index 3799b594..9909e745 100644
--- a/go/handlers/peerHandler.go
+++ b/go/handlers/peerHandler.go
@@ -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)
}
}
diff --git a/go/ui/gcd.go b/go/ui/gcd.go
index b4ebe0dc..64bd1bbd 100644
--- a/go/ui/gcd.go
+++ b/go/ui/gcd.go
@@ -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 {
diff --git a/go/ui/manager.go b/go/ui/manager.go
index 3ad2fe73..53f8f38e 100644
--- a/go/ui/manager.go
+++ b/go/ui/manager.go
@@ -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))
})
}
diff --git a/qml.qrc b/qml.qrc
index c524d5b1..cfb4b0f6 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -28,6 +28,7 @@
qml/widgets/InplaceEditText.qml
qml/widgets/Message.qml
qml/widgets/ScalingLabel.qml
+ qml/widgets/EllipsisLabel.qml
qml/widgets/MyProfile.qml
qml/widgets/ProfileList.qml
qml/widgets/RadioButton.qml
diff --git a/qml/main.qml b/qml/main.qml
index c1a58094..c83d2948 100644
--- a/qml/main.qml
+++ b/qml/main.qml
@@ -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
}
}
diff --git a/qml/styles/CwtchTextFieldStyle.qml b/qml/styles/CwtchTextFieldStyle.qml
index 5b17266d..83225859 100644
--- a/qml/styles/CwtchTextFieldStyle.qml
+++ b/qml/styles/CwtchTextFieldStyle.qml
@@ -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
diff --git a/qml/widgets/ContactList.qml b/qml/widgets/ContactList.qml
index 13630fbb..67244d5c 100644
--- a/qml/widgets/ContactList.qml
+++ b/qml/widgets/ContactList.qml
@@ -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
}
diff --git a/qml/widgets/EllipsisLabel.qml b/qml/widgets/EllipsisLabel.qml
new file mode 100644
index 00000000..71e6f09e
--- /dev/null
+++ b/qml/widgets/EllipsisLabel.qml
@@ -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++
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/qml/widgets/Message.qml b/qml/widgets/Message.qml
index ee97fd07..2ad33ef2 100644
--- a/qml/widgets/Message.qml
+++ b/qml/widgets/Message.qml
@@ -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
diff --git a/qml/widgets/MyProfile.qml b/qml/widgets/MyProfile.qml
index 087959fe..0fea4fc9 100644
--- a/qml/widgets/MyProfile.qml
+++ b/qml/widgets/MyProfile.qml
@@ -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
- }
+ }*/
}
}
diff --git a/qml/widgets/Portrait.qml b/qml/widgets/Portrait.qml
index d405c032..ce9526cb 100644
--- a/qml/widgets/Portrait.qml
+++ b/qml/widgets/Portrait.qml
@@ -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
diff --git a/qml/widgets/PortraitRow.qml b/qml/widgets/PortraitRow.qml
index d506ce58..953edfc8 100644
--- a/qml/widgets/PortraitRow.qml
+++ b/qml/widgets/PortraitRow.qml
@@ -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)" : "")
}
}