diff --git a/go/ui/gcd.go b/go/ui/gcd.go
index 7114b3ec..b4ebe0dc 100644
--- a/go/ui/gcd.go
+++ b/go/ui/gcd.go
@@ -48,14 +48,14 @@ type GrandCentralDispatcher struct {
_ func(failed bool) `signal:"ChangePasswordResponse"`
// contact list stuff
- _ func(handle, displayName, image, server string, badge, status int, blocked bool, loading bool, lastMsgTime int) `signal:"AddContact"`
- _ func(handle, displayName string) `signal:"UpdateContactDisplayName"`
- _ func(handle, image string) `signal:"UpdateContactPicture"`
- _ func(handle string, status int, loading bool) `signal:"UpdateContactStatus"`
- _ func(handle string, blocked bool) `signal:"UpdateContactBlocked"`
- _ func(handle string) `signal:"IncContactUnreadCount"`
- _ func(handle string) `signal:"RemoveContact"`
- _ func(handle, key, value string) `signal:"UpdateContactAttribute"`
+ _ func(handle, displayName, image string, badge, status int, blocked bool, loading bool, lastMsgTime int) `signal:"AddContact"`
+ _ func(handle, displayName string) `signal:"UpdateContactDisplayName"`
+ _ func(handle, image string) `signal:"UpdateContactPicture"`
+ _ func(handle string, status int, loading bool) `signal:"UpdateContactStatus"`
+ _ func(handle string, blocked bool) `signal:"UpdateContactBlocked"`
+ _ func(handle string) `signal:"IncContactUnreadCount"`
+ _ func(handle string) `signal:"RemoveContact"`
+ _ func(handle, key, value string) `signal:"UpdateContactAttribute"`
// messages pane stuff
_ func(handle, from, displayName, message, image string, mID string, fromMe bool, ts string, ackd bool, error bool) `signal:"AppendMessage"`
@@ -590,6 +590,9 @@ func (this *GrandCentralDispatcher) unlockProfiles(password string) {
func (this *GrandCentralDispatcher) loadProfile(onion string) {
the.Peer = the.CwtchApp.GetPeer(onion)
+ if the.Peer == nil {
+ return
+ }
the.EventBus = the.CwtchApp.GetEventBus(onion)
picVal, exists := the.Peer.GetAttribute(attr.GetPublicScope(constants.Picture))
diff --git a/go/ui/manager.go b/go/ui/manager.go
index d5355c4d..3ad2fe73 100644
--- a/go/ui/manager.go
+++ b/go/ui/manager.go
@@ -242,7 +242,7 @@ func (this *manager) AddContact(handle string) {
unread := countUnread(group.Timeline.GetMessages(), lastRead)
picture := getProfilePic(handle)
- this.gcd.AddContact(handle, getNick(handle), picture, group.GroupServer, unread, int(connections.ConnectionStateToType[group.State]), false, false, getLastMessageTime(&group.Timeline))
+ this.gcd.AddContact(handle, getNick(handle), picture, unread, int(connections.ConnectionStateToType[group.State]), false, false, getLastMessageTime(&group.Timeline))
}
return
} else if !isPeer(handle) {
@@ -257,7 +257,7 @@ func (this *manager) AddContact(handle string) {
unread := countUnread(contact.Timeline.GetMessages(), lastRead)
picture := getProfilePic(handle)
- this.gcd.AddContact(handle, getNick(handle), picture, "", unread, int(connections.ConnectionStateToType[contact.State]), contact.Blocked, false, getLastMessageTime(&contact.Timeline))
+ this.gcd.AddContact(handle, getNick(handle), picture, unread, int(connections.ConnectionStateToType[contact.State]), contact.Blocked, false, getLastMessageTime(&contact.Timeline))
}
})
}
diff --git a/qml.qrc b/qml.qrc
index 7fa985ce..c524d5b1 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -18,7 +18,10 @@
qml/styles/CwtchTextAreaStyle.qml
qml/styles/CwtchTextFieldStyle.qml
qml/widgets/ContactList.qml
- qml/widgets/ContactPicture.qml
+ qml/widgets/Portrait.qml
+ qml/widgets/Badge.qml
+ qml/widgets/PortraitRow.qml
+ qml/widgets/ProfileRow.qml
qml/widgets/ContactRow.qml
qml/widgets/EmojiDrawer.qml
qml/widgets/FontAwesome.qml
diff --git a/qml/main.qml b/qml/main.qml
index 9de89540..c1a58094 100644
--- a/qml/main.qml
+++ b/qml/main.qml
@@ -126,21 +126,15 @@ ApplicationWindow {
RowLayout { // CONTAINS EVERYTHING EXCEPT THE TOOLBAR
- /* anchors.left: ratio >= 0.92 ? parent.left : toolbar.right
- anchors.top: ratio >= 0.92 ? toolbar.bottom : parent.top
- anchors.right: parent.right
- anchors.bottom: parent.bottom */
anchors.fill: parent
spacing: 0
-
-
Rectangle { // THE LEFT PANE WITH TOOLS AND CONTACTS
color: "#D2C0DD"
Layout.fillHeight: true
Layout.minimumWidth: Layout.maximumWidth
- Layout.maximumWidth: theStack.pane == theStack.emptyPane ? parent.width : 450
- visible: (ratio <= 1.08 && windowItem.width >= 700 && !Qt.inputMethod.visible) || theStack.pane == theStack.emptyPane
+ Layout.maximumWidth: theStack.pane == theStack.emptyPane ? parent.width : Theme.sidePaneMinSize
+ visible: (windowItem.width >= Theme.doublePaneMinSize && !Qt.inputMethod.visible) || theStack.pane == theStack.emptyPane
ContactList{
diff --git a/qml/overlays/MembershipOverlay.qml b/qml/overlays/MembershipOverlay.qml
index b9297717..586b2d6f 100644
--- a/qml/overlays/MembershipOverlay.qml
+++ b/qml/overlays/MembershipOverlay.qml
@@ -106,7 +106,6 @@ ColumnLayout {
displayName: _displayName
image: _image
blocked: false
- background: false
}
}
}
diff --git a/qml/theme/CwtchDark.qml b/qml/theme/CwtchDark.qml
index f52cc6cc..14d0ed2b 100644
--- a/qml/theme/CwtchDark.qml
+++ b/qml/theme/CwtchDark.qml
@@ -6,12 +6,28 @@ ThemeType {
readonly property color purple: "#DFB9DE"
readonly property color whitePurple: "#FFFDFF"
readonly property color softPurple: "#FDF3FC"
- readonly property color hotPink: "#d01972"
+ readonly property color pink: "#E85DA1"
+ readonly property color hotPink: "#D01972"
backgroundMainColor: darkGrayPurple
backgroundPaneColor: mauvePurple
mainTextColor: whitePurple
defaultButtonColor: hotPink
+ defaultButtonActiveColor: pink
defaultButtonTextColor: whitePurple
+
+ portraitOnlineBorderColor: whitePurple
+ portraitOnlineBackgroundColor: darkGrayPurple
+ portraitOnlineTextColor: whitePurple
+ portraitConnectingBorderColor: mauvePurple
+ portraitConnectingBackgroundColor: darkGrayPurple
+ portraitConnectingTextColor: whitePurple
+ portraitOfflineBorderColor: deepPurple
+ portraitOfflineBackgroundColor: darkGrayPurple
+ portraitOfflineTextColor: softPurple
+
+ portraitContactBadgeColor: hotPink
+ portraitContactBadgeTextColor: whitePurple
+ portraitProfileBadgeColor: mauvePurple
}
\ No newline at end of file
diff --git a/qml/theme/CwtchLight.qml b/qml/theme/CwtchLight.qml
index ce1635ec..aad84706 100644
--- a/qml/theme/CwtchLight.qml
+++ b/qml/theme/CwtchLight.qml
@@ -2,16 +2,32 @@
ThemeType {
readonly property color whitePurple: "#FFFDFF"
readonly property color softPurple: "#FDF3FC"
- readonly property color purple: "#FDF3FC"
+ readonly property color purple: "#DFB9DE"
readonly property color brightPurple: "#760388"
readonly property color darkPurple: "#350052"
readonly property color greyPurple: "#775F84"
- readonly property color hotPink: "#d01972"
+ readonly property color pink: "#E85DA1"
+ readonly property color hotPink: "#D01972"
backgroundMainColor: whitePurple
- backgroundPaneColor: purple
+ backgroundPaneColor: softPurple
mainTextColor: darkPurple
defaultButtonColor: hotPink
+ defaultButtonActiveColor: pink
defaultButtonTextColor: whitePurple
+
+ portraitOnlineBorderColor: darkPurple
+ portraitOnlineBackgroundColor: darkPurple
+ portraitOnlineTextColor: darkPurple
+ portraitConnectingBorderColor: greyPurple
+ portraitConnectingBackgroundColor: greyPurple
+ portraitConnectingTextColor: greyPurple
+ portraitOfflineBorderColor: purple
+ portraitOfflineBackgroundColor: purple
+ portraitOfflineTextColor: purple
+
+ portraitContactBadgeColor: hotPink
+ portraitContactBadgeTextColor: whitePurple
+ portraitProfileBadgeColor: brightPurple
}
\ No newline at end of file
diff --git a/qml/theme/Theme.qml b/qml/theme/Theme.qml
index 1023db74..5fc5685b 100644
--- a/qml/theme/Theme.qml
+++ b/qml/theme/Theme.qml
@@ -8,7 +8,33 @@ Item {
readonly property color mainTextColor: theme.mainTextColor
readonly property color defaultButtonColor: theme.defaultButtonColor
+ readonly property color defaultButtonActiveColor: theme.defaultButtonActiveColor
readonly property color defaultButtonTextColor: theme.defaultButtonTextColor
+ readonly property color portraitOnlineBorderColor: theme.portraitOnlineBorderColor
+ readonly property color portraitOnlineBackgroundColor: theme.portraitOnlineBackgroundColor
+ readonly property color portraitOnlineTextColor: theme.portraitOnlineTextColor
+ readonly property color portraitConnectingBorderColor: theme.portraitConnectingBorderColor
+ readonly property color portraitConnectingBackgroundColor: theme.portraitConnectingBackgroundColor
+ readonly property color portraitConnectingTextColor: theme.portraitConnectingTextColor
+ readonly property color portraitOfflineBorderColor: theme.portraitOfflineBorderColor
+ readonly property color portraitOfflineBackgroundColor: theme.portraitOfflineBackgroundColor
+ readonly property color portraitOfflineTextColor: theme.portraitOfflineTextColor
+
+ readonly property color portraitContactBadgeColor: theme.portraitContactBadgeColor
+ readonly property color portraitContactBadgeTextColor: theme.portraitContactBadgeTextColor
+ readonly property color portraitProfileBadgeColor: theme.portraitProfileBadgeColor
+
+ readonly property int headerSize: 50
+ readonly property int usernameSize: 30
+ readonly property int tabSize: 25
+ readonly property int chatSize: 20
+ readonly property int secondaryTextSize: 20 // address
+ readonly property int chatMetaTextSize: 15
+ readonly property int badgeTextSize: 12
+
+ readonly property int sidePaneMinSize: 700
+ readonly property int doublePaneMinSize: 1000
+
property ThemeType theme: CwtchLight { }
}
\ No newline at end of file
diff --git a/qml/theme/ThemeType.qml b/qml/theme/ThemeType.qml
index cd8aa725..174c190a 100644
--- a/qml/theme/ThemeType.qml
+++ b/qml/theme/ThemeType.qml
@@ -6,7 +6,23 @@ QtObject {
property color mainTextColor: "red"
property color defaultButtonColor: "red"
+ property color defaultButtonActiveColor: "red"
property color defaultButtonTextColor: "red"
+
+ property color portraitOnlineBorderColor: "red"
+ property color portraitOnlineBackgroundColor: "red"
+ property color portraitOnlineTextColor: "red"
+ property color portraitConnectingBorderColor: "red"
+ property color portraitConnectingBackgroundColor: "red"
+ property color portraitConnectingTextColor: "red"
+ property color portraitOfflineBorderColor: "red"
+ property color portraitOfflineBackgroundColor: "red"
+ property color portraitOfflineTextColor: "red"
+
+ property color portraitContactBadgeColor: "red"
+ property color portraitContactBadgeTextColor: "red"
+ property color portraitProfileBadgeColor: "red"
+
// ... more to come
diff --git a/qml/widgets/Badge.qml b/qml/widgets/Badge.qml
new file mode 100644
index 00000000..7cf04d36
--- /dev/null
+++ b/qml/widgets/Badge.qml
@@ -0,0 +1,24 @@
+import QtGraphicalEffects 1.0
+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 "../theme"
+
+Rectangle {
+ width: parent.width * 0.25
+ height: width
+ radius: width/2
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ anchors.margins: parent.width * 0.15
+ property alias content: container.children
+
+ Column {
+ id: container
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+}
\ No newline at end of file
diff --git a/qml/widgets/Button.qml b/qml/widgets/Button.qml
index 64502b90..dacb9c17 100644
--- a/qml/widgets/Button.qml
+++ b/qml/widgets/Button.qml
@@ -15,7 +15,7 @@ Rectangle {
height: 20 * gcd.themeScale
Layout.minimumHeight: height
Layout.maximumHeight: height
- color: mousedown ? Qt.lighter(Theme.defaultButtonColor, 1.5) : Theme.defaultButtonColor
+ color: mousedown ? Theme.defaultButtonActiveColor : Theme.defaultButtonColor
border.color: Theme.defaultButtonColor
border.width: 1
radius: (height / 2.0)
diff --git a/qml/widgets/ContactList.qml b/qml/widgets/ContactList.qml
index 1552475d..13630fbb 100644
--- a/qml/widgets/ContactList.qml
+++ b/qml/widgets/ContactList.qml
@@ -47,7 +47,7 @@ ColumnLayout {
Connections { // ADD/REMOVE CONTACT ENTRIES
target: gcd
- onAddContact: function(handle, displayName, image, server, badge, status, blocked, loading, lastMsgTs) {
+ onAddContact: function(handle, displayName, image, badge, status, blocked, loading, lastMsgTs) {
for (var i = 0; i < contactsModel.count; i++) {
if (contactsModel.get(i)["_handle"] == handle) {
@@ -67,7 +67,6 @@ ColumnLayout {
"_handle": handle,
"_displayName": displayName + (blocked ? " (blocked)" : "" ),
"_image": image,
- "_server": server,
"_badge": badge,
"_status": status,
"_blocked": blocked,
@@ -95,7 +94,6 @@ ColumnLayout {
if(contactsModel.get(i)["_handle"] == handle) {
var contact = contactsModel.get(i)
contact["_lastMsgTs"] = ts
- console.log("Found at " + i + " contact: " + contact)
contactsModel.move(i, 0, 1)
}
}
@@ -116,12 +114,10 @@ ColumnLayout {
handle: _handle
displayName: _displayName
image: _image
- server: _server
badge: _badge
status: _status
blocked: _blocked
loading: _loading
- type: "contact"
}
}
diff --git a/qml/widgets/ContactPicture.qml b/qml/widgets/ContactPicture.qml
deleted file mode 100644
index ca7b9925..00000000
--- a/qml/widgets/ContactPicture.qml
+++ /dev/null
@@ -1,85 +0,0 @@
-import QtGraphicalEffects 1.0
-import QtQuick 2.7
-import QtQuick.Controls 2.4
-import QtQuick.Controls.Material 2.0
-import QtQuick.Layouts 1.3
-import CustomQmlTypes 1.0
-
-Item {
- id: imgProfile
- implicitWidth: baseWidth
- implicitHeight: baseWidth
- anchors.margins: 5
-
- property string handle
- property string source
- property int status
- property bool isGroup
- property bool showStatus
- property bool highlight
- property bool button
- property real logscale: 4 * Math.log10(gcd.themeScale + 1)
- property int baseWidth: 48 * logscale
-
- Rectangle {
- id: mainImage
- width: baseWidth
- height: baseWidth
- color: "#350052" //: "#FFFFFF" //windowItem.cwtch_dark_color: "#FFFFFF"
- radius: width / 2
-
- Rectangle {
- width: highlight ? baseWidth - 4 : baseWidth
- height: highlight ? baseWidth - 4 : baseWidth
- color: "#350052" //: "#FFFFFF" // windowItem.cwtch_dark_color: "#FFFFFF"
- radius: width / 2
- anchors.centerIn:parent
-
-
- Image { // PROFILE IMAGE
- id: img
- source: gcd.assetPath + imgProfile.source
- anchors.fill: parent
- fillMode: Image.PreserveAspectFit
- visible: false
- }
-
- Image { // CIRCLE MASK
- id: mask
- fillMode: Image.PreserveAspectFit
- visible: false
- source: "qrc:/qml/images/extra/clipcircle.png"
- }
-
- OpacityMask {
- anchors.fill: img
- source: img
- maskSource: mask
- }
-
- }
-
- Rectangle { // PRESENCE INDICATOR
- visible: showStatus
- color: "#FFFFFF"
- width: 8 * logscale
- height: 8 * logscale
- radius: 2 * logscale
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- anchors.margins: 4 * logscale
-
-
- Rectangle { //-2:WtfCodeError,-1:Error,0:Disconnected,1:Connecting,2:Connected,3:Authenticated,4:Synced,5:Failed,6:Killed
- color: status == 4 ? "green" : status == 3 ? "green" : status == -1 ? "blue" : status == 1 ? "orange" : status == 2 ? "orange" : "red"
- width: 5 * logscale
- height: 5 * logscale
- radius: 2 * logscale
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- anchors.margins: 1.5 * logscale
- }
- }
-
- }
-}
\ No newline at end of file
diff --git a/qml/widgets/ContactRow.qml b/qml/widgets/ContactRow.qml
index 2da8f502..ce315713 100644
--- a/qml/widgets/ContactRow.qml
+++ b/qml/widgets/ContactRow.qml
@@ -6,255 +6,97 @@ import QtQuick.Layouts 1.3
import CustomQmlTypes 1.0
import "../styles"
import "../widgets" as Widgets
+import "../theme"
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
+PortraitRow {
-Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
- id: crItem
- anchors.left: parent.left
- anchors.right: parent.right
- height: 48 * logscale + 3
- implicitHeight: height
-
- property real logscale: 4 * Math.log10(gcd.themeScale + 1)
- property alias displayName: cn.text
- property alias image: imgProfile.source
- property string handle
- property int badge
- property bool isActive
- property bool isHover
- property bool background: true
- property string type // profile or contact or button
- property string tag // profile version/type
-
- // Profile
- property bool defaultPassword
-
- // Contact
- property bool blocked
+ property int status: 0
+ property int badge
property bool loading
- property alias status: imgProfile.status
- property string server
+ badgeColor: Theme.portraitContactBadgeColor
+ badgeVisible: badge > 0
- Rectangle { // CONTACT ENTRY BACKGROUND COLOR
- id: crRect
- anchors.left: parent.left
- anchors.right: parent.right
- height: 48 * logscale + 3
- width: parent.width
- color: background ? (isHover ? "#D2D2F3" : (isActive ? "#D2D2F3" : "#D2C0DD")) : windowItem.cwtch_background_color
-
- ContactPicture {
- id: imgProfile
- showStatus: type == "contact"
- button: type == "button"
- }
-
- ColumnLayout {
-
- anchors.left: imgProfile.right
- anchors.right: loading ? loadingProgress.left : rectUnread.left
- anchors.verticalCenter: parent.verticalCenter
-
-
- Label { // CONTACT NAME
- id: cn
- leftPadding: 10
- rightPadding: 10
- //wrapMode: Text.WordWrap
- font.pixelSize: 16 * gcd.themeScale
- font.strikeout: blocked
- textFormat: Text.PlainText
- //fontSizeMode: Text.HorizontalFit
- elide: Text.ElideRight
- color: "#000000"
- }
-
- Label { // Onion
- id: onion
- text: handle
- leftPadding: 10
- rightPadding: 10
- font.pixelSize: 10 * gcd.themeScale
- font.strikeout: blocked
- textFormat: Text.PlainText
- //fontSizeMode: Text.HorizontalFit
- elide: Text.ElideRight
- color: "#000000"
- }
-
- }
-
- Rectangle { // UNREAD MESSAGES?
- id: rectUnread
- height: txtmetric.tightBoundingRect.height + 8 * gcd.themeScale
- width: txtmetric.tightBoundingRect.width + 8 * gcd.themeScale
- radius: 8 * gcd.themeScale
- color: "#4B3557"
- visible: badge != 0
- anchors.verticalCenter: parent.verticalCenter
- anchors.right: parent.right
- anchors.rightMargin: 9 * gcd.themeScale
-
- Label {
- id: lblUnread
- anchors.verticalCenter: parent.verticalCenter
- anchors.horizontalCenter: parent.horizontalCenter
- color: "#FFFFFF"
- font.pixelSize: 12 * gcd.themeScale
- text: txtmetric.text
- }
-
- TextMetrics {
- id: txtmetric
- text: badge
- font: lblUnread.font
- }
- }
-
- // Profile
-
- Image {// Profle Type
- id: profiletype
-
- source: tag == "v1-userPassword" ? gcd.assetPath + "/fontawesome/solid/lock.svg" : gcd.assetPath + "/fontawesome/solid/lock-open.svg"
-
- anchors.right: parent.right
-
- anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: 1 * gcd.themeScale
- anchors.rightMargin: (20 * gcd.themeScale) + parent.height
- height: parent.height * 0.5
- width: height
-
- visible: type == "profile"
-
- }
-
-
- // Contact
- ProgressBar { // LOADING ?
- id: loadingProgress
- property bool running
- running: loading
- visible: loading
-
- anchors.right: rectUnread.left
- anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: 1 * gcd.themeScale
- anchors.rightMargin: 1 * gcd.themeScale
-
-
- height: cn.height/2
- width: 100 * gcd.themeScale
-
-
-
- indeterminate: true
-
- style: ProgressBarStyle {
- progress: CwtchProgress { running: loadingProgress.running}
- }
- }
-
- }
-
- MouseArea { // ONCLICK: LOAD CONVERSATION WITH THIS CONTACT
- anchors.fill: parent
- hoverEnabled: true
-
- onClicked: {
- if (type == "contact") {
- if (displayName != "me") {
- gcd.broadcast("ResetMessagePane")
- isActive = true
- theStack.pane = theStack.messagePane
- gcd.loadMessagesPane(handle)
- badge = 0
- if (handle.length == 32) {
- gcd.requestGroupSettings(handle)
- }
- }
- } else if (type == "profile") {
- gcd.broadcast("ResetMessagePane")
- gcd.broadcast("ResetProfile")
- gcd.selectedProfile = handle
- gcd.loadProfile(handle)
- parentStack.pane = parentStack.profilePane
- } else if (type == "button") { // Add profile button
- profileAddEditPane.reset()
- parentStack.pane = parentStack.addEditProfilePane
- }
- }
-
- onEntered: {
- isHover = true
- }
-
- onExited: {
- isHover = false
- }
- }
-
- Widgets.Button {// Edit BUTTON
- id: btnEdit
- icon: "solid/user-edit"
-
- anchors.right: parent.right
-
- //rectUnread.left
- anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: 1 * gcd.themeScale
- anchors.rightMargin: 20 * gcd.themeScale
- height: parent.height * 0.75
-
- visible: type == "profile"
-
-
- onClicked: {
- profileAddEditPane.load(handle, displayName, tag)
- parentStack.pane = parentStack.addEditProfilePane
- }
+ badgeContent: Label {
+ id: lblUnread
+ color: Theme.portraitContactBadgeTextColor
+ font.pixelSize: Theme.badgeTextSize * gcd.themeScale
+ font.weight: Font.Bold
+ text: badge > 99 ? "99+" : badge
}
- Connections { // UPDATE UNREAD MESSAGES COUNTER
- target: gcd
+ ProgressBar { // LOADING ?
+ id: loadingProgress
+ property bool running
+ running: loading
+ visible: loading
- onResetMessagePane: function() {
- isActive = false
- }
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.leftMargin: 1 * gcd.themeScale
+ anchors.rightMargin: 25 * gcd.themeScale
- onUpdateContactStatus: function(_handle, _status, _loading) {
- if (handle == _handle) {
- status = _status
- loadingProgress.visible = loadingProgress.running = loading = _loading
+ height: parent.height * .1
+ width: 100 * gcd.themeScale
+
+ indeterminate: true
+
+ style: ProgressBarStyle {
+ progress: CwtchProgress { running: loadingProgress.running}
+ }
+ }
+
+ onClicked: function(handle) {
+ gcd.broadcast("ResetMessagePane")
+ isActive = true
+ theStack.pane = theStack.messagePane
+ gcd.loadMessagesPane(handle)
+ badge = 0
+ if (handle.length == 32) {
+ gcd.requestGroupSettings(handle)
+ }
+ }
+
+ Component.onCompleted: { setColors(status) }
+
+ onStatusChanged: { setColors(status) }
+
+ function setColors(status) {
+ //-2:WtfCodeError,-1:Error,0:Disconnected,1:Connecting,2:Connected,3:Authenticated,4:Synced,5:Failed,6:Killed
+ if (status == 4 || status == 3) {
+ portraitBorderColor = Theme.portraitOnlineBorderColor
+ portraitColor = Theme.portraitOnlineBackgroundColor
+ nameColor = Theme.portraitOnlineTextColor
+ onionColor = Theme.portraitOnlineTextColor
+ } else if (status == 2 || status == 1) {
+ portraitBorderColor = Theme.portraitConnectingBorderColor
+ portraitColor = Theme.portraitConnectingBackgroundColor
+ nameColor = Theme.portraitConnectingTextColor
+ onionColor = Theme.portraitConnectingTextColor
+ } else {
+ portraitBorderColor = Theme.portraitOfflineBorderColor
+ portraitColor = Theme.portraitOfflineBackgroundColor
+ nameColor = Theme.portraitOfflineTextColor
+ onionColor = Theme.portraitOfflineTextColor
+ }
+ }
+
+ Connections { // UPDATE UNREAD MESSAGES COUNTER
+ target: gcd
+
+ onUpdateContactStatus: function(_handle, _status, _loading) {
+ if (handle == _handle) {
+ status = _status
+ loadingProgress.visible = loadingProgress.running = loading = _loading
+ }
+ }
+
+ onIncContactUnreadCount: function(handle) {
+ if (handle == _handle && gcd.selectedConversation != handle) {
+ badge++
}
}
-
- onUpdateContactBlocked: function(_handle, _blocked) {
- if (handle == _handle) {
- blocked = _blocked
- }
- }
-
- onUpdateContactDisplayName: function(_handle, _displayName) {
- if (handle == _handle) {
- displayName = _displayName + (_blocked == true ? " (blocked)" : "")
- }
- }
-
- onUpdateContactPicture: function(_handle, _image) {
- if (handle == _handle) {
- image = _image
- }
- }
-
- onIncContactUnreadCount: function(handle) {
- if (handle == _handle && gcd.selectedConversation != handle) {
- badge++
- }
- }
- }
-}
+ }
+}
\ No newline at end of file
diff --git a/qml/widgets/Message.qml b/qml/widgets/Message.qml
index d59b2fe1..ee97fd07 100644
--- a/qml/widgets/Message.qml
+++ b/qml/widgets/Message.qml
@@ -23,7 +23,6 @@ Item {
property bool ackd
property alias timestamp: ts.text
property alias image: imgProfile.source
- property alias status: imgProfile.status
property string error
Connections {
@@ -43,13 +42,13 @@ Item {
}
- ContactPicture {
+ Portrait {
id: imgProfile
anchors.left: parent.left
handle: root.from
visible: !fromMe
- showStatus: false
- highlight: ima.containsMouse
+ //showStatus: false
+ //highlight: ima.containsMouse
ToolTip.visible: ima.containsMouse
//: Click to DM
diff --git a/qml/widgets/Portrait.qml b/qml/widgets/Portrait.qml
new file mode 100644
index 00000000..d405c032
--- /dev/null
+++ b/qml/widgets/Portrait.qml
@@ -0,0 +1,68 @@
+import QtGraphicalEffects 1.0
+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 "../theme"
+
+Item {
+ id: imgProfile
+ 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 alias portraitBorderColor: mainImage.color
+ property alias portraitColor: imageInner.color
+ property alias badgeVisible: badge.visible
+ property alias badgeContent: badge.content
+
+ Rectangle {
+ id: mainImage
+ width: baseWidth * 0.8
+ height: width
+ anchors.verticalCenter: parent.verticalCenter
+ color: Theme.portraitOfflineBorderColor
+ radius: width / 2
+
+ Rectangle {
+ id: imageInner
+ width: parent.width - 4
+ height: width
+ color: Theme.portraitOfflineBorderColor
+ radius: width / 2
+ anchors.centerIn:parent
+
+ Image { // PROFILE IMAGE
+ id: img
+ source: gcd.assetPath + imgProfile.source
+ anchors.fill: parent
+ fillMode: Image.PreserveAspectFit
+ visible: false
+ }
+
+ Image { // CIRCLE MASK
+ id: mask
+ fillMode: Image.PreserveAspectFit
+ visible: false
+ source: "qrc:/qml/images/extra/clipcircle.png"
+ }
+
+ OpacityMask {
+ anchors.fill: img
+ source: img
+ maskSource: mask
+ }
+ }
+ }
+
+ Badge {
+ id: badge
+ }
+}
\ No newline at end of file
diff --git a/qml/widgets/PortraitRow.qml b/qml/widgets/PortraitRow.qml
new file mode 100644
index 00000000..d506ce58
--- /dev/null
+++ b/qml/widgets/PortraitRow.qml
@@ -0,0 +1,160 @@
+import QtGraphicalEffects 1.0
+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 "../styles"
+import "../widgets" as Widgets
+import "../theme"
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+
+Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
+ id: crItem
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: 78 * logscale + 3
+ implicitHeight: 78 * logscale + 3 //height
+
+ property real logscale: 4 * Math.log10(gcd.themeScale + 1)
+ property string displayName //: nameTxtmetric.text
+ property alias image: portrait.source
+ property string handle
+ property bool isActive
+ property bool isHover
+ property string tag // profile version/type
+
+ property alias badgeColor: portrait.badgeColor
+ property alias portraitBorderColor: portrait.portraitBorderColor
+ property alias portraitColor: portrait.portraitColor
+ property alias nameColor: cn.color
+ property alias onionColor: onion.color
+ property alias badgeVisible: portrait.badgeVisible
+ property alias badgeContent: portrait.badgeContent
+
+
+ // TODO: should be in ContactRow
+ property bool blocked
+
+ signal clicked(string handle)
+
+ Rectangle { // CONTACT ENTRY BACKGROUND COLOR
+ id: crRect
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: crItem.height
+ width: parent.width
+ color: isHover ? Theme.backgroundPaneColor : (isActive ? Theme.backgroundPaneColor : Theme.backgroundMainColor)
+
+ Portrait {
+ id: portrait
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ anchors.leftMargin: 25 * logscale
+ }
+
+ ColumnLayout {
+
+ anchors.left: portrait.right
+ anchors.leftMargin: 4 * logscale
+ anchors.verticalCenter: parent.verticalCenter
+
+ Label { // 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
+ text: displayName
+ font: cn.font
+ }
+
+
+ Label { // 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
+ }
+
+ TextMetrics {
+ id: onionTxtmetric
+ text: handle
+ font: onion.font
+ }
+
+ }
+
+ 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++
+ }
+ }
+ }
+
+ MouseArea { // Full row mouse area triggering onClick
+ id: buttonMA
+ anchors.fill: parent
+ hoverEnabled: true
+
+ onClicked: { crItem.clicked(crItem.handle) }
+
+ onEntered: {
+ isHover = true
+ }
+
+ onExited: {
+ isHover = false
+ }
+ }
+
+ Connections { // UPDATE UNREAD MESSAGES COUNTER
+ target: gcd
+
+ onResetMessagePane: function() {
+ isActive = false
+ }
+
+ onUpdateContactBlocked: function(_handle, _blocked) {
+ if (handle == _handle) {
+ blocked = _blocked
+ }
+ }
+
+ onUpdateContactDisplayName: function(_handle, _displayName) {
+ if (handle == _handle) {
+ displayName = _displayName + (_blocked == true ? " (blocked)" : "")
+ }
+ }
+
+ onUpdateContactPicture: function(_handle, _image) {
+ if (handle == _handle) {
+ image = _image
+ }
+ }
+ }
+}
diff --git a/qml/widgets/ProfileList.qml b/qml/widgets/ProfileList.qml
index 8c69e28b..512ab35f 100644
--- a/qml/widgets/ProfileList.qml
+++ b/qml/widgets/ProfileList.qml
@@ -3,11 +3,11 @@ import QtQuick 2.7
import QtQuick.Controls 2.4
import QtQuick.Controls.Material 2.0
import QtQuick.Layouts 1.3
+import "../theme"
ColumnLayout {
id: root
-
MouseArea {
anchors.fill: parent
@@ -44,7 +44,6 @@ ColumnLayout {
onAddProfile: function(handle, displayName, image, tag) {
// don't add duplicates
- console.log("ProfileList onAddProfile for: " + handle)
for (var i = 0; i < profilesModel.count; i++) {
if (profilesModel.get(i)["_handle"] == handle) {
return
@@ -52,8 +51,8 @@ ColumnLayout {
}
// find index for insert (sort by onion)
- var index = profilesModel.count-1
- for (var i = 0; i < profilesModel.count-1; i++) {
+ var index = profilesModel.count
+ for (var i = 0; i < profilesModel.count; i++) {
if (profilesModel.get(i)["_handle"] > handle) {
index = i
break
@@ -62,11 +61,11 @@ ColumnLayout {
profilesModel.insert(index,
{
- "_handle": handle,
- "_displayName": displayName,
- "_image": image,
- "_type": "profile",
- "_tag": tag
+ _handle: handle,
+ _displayName: displayName,
+ _image: image,
+ _tag: tag,
+ _status: 4,
})
}
@@ -83,43 +82,41 @@ ColumnLayout {
onResetProfileList: function() {
profilesModel.clear()
- profilesModel.append({
- _handle: "",
- _displayName: qsTr("add-new-profile-btn"),
- _image: "/fontawesome/solid/user-plus.svg",
- _type: "button",
- _tag: ","
- })
}
}
ListModel { // Profile OBJECTS ARE STORED HERE ...
id: profilesModel
-
- ListElement {
- _handle: ""
- _displayName: qsTr("add-new-profile-btn")
- _image: "/fontawesome/solid/user-plus.svg"
- _type: "button"
- _tag: ""
- }
}
Repeater {
+ id: profileList
model: profilesModel // ... AND DISPLAYED HERE
- delegate: ContactRow {
+ delegate: ProfileRow {
handle: _handle
displayName: _displayName
image: _image
- server: ""
- badge: 0
- status: 0
blocked: false
- loading: false
- type: _type
tag: _tag
}
}
- }
+
+ PortraitRow {
+ handle: ""
+ displayName: qsTr("add-new-profile-btn")
+ image: "/fontawesome/regular/user.svg"
+ tag: ""
+ portraitBorderColor: Theme.defaultButtonColor
+ portraitColor: Theme.defaultButtonColor
+ badgeVisible: true
+ badgeContent: Image {
+ source: gcd.assetPath + "/fontawesome/solid/plus.svg"
+ height: Theme.badgeTextSize * gcd.themeScale
+ width: height
+ }
+ badgeColor: Theme.portraitOnlineBorderColor
+ onClicked: function(handle) { profileAddEditPane.reset(); parentStack.pane = parentStack.addEditProfilePane }
+ }
+ }
}
}
diff --git a/qml/widgets/ProfileRow.qml b/qml/widgets/ProfileRow.qml
new file mode 100644
index 00000000..6a48be9b
--- /dev/null
+++ b/qml/widgets/ProfileRow.qml
@@ -0,0 +1,56 @@
+import QtGraphicalEffects 1.0
+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 "../styles"
+import "../widgets" as Widgets
+import "../theme"
+import QtQuick.Controls 1.4
+import QtQuick.Controls.Styles 1.4
+
+PortraitRow {
+
+ badgeColor: Theme.portraitProfileBadgeColor
+
+ portraitBorderColor: Theme.portraitOnlineBorderColor
+ portraitColor: Theme.portraitOnlineBackgroundColor
+ nameColor: Theme.portraitOnlineTextColor
+ onionColor: Theme.portraitOnlineTextColor
+
+ 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
+ }
+
+ Widgets.Button {// Edit BUTTON
+ id: btnEdit
+ icon: "solid/user-edit"
+
+ anchors.right: parent.right
+
+ //rectUnread.left
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.leftMargin: 1 * gcd.themeScale
+ anchors.rightMargin: 20 * gcd.themeScale
+ height: parent.height * 0.75
+
+
+
+ onClicked: {
+ profileAddEditPane.load(handle, displayName, tag)
+ parentStack.pane = parentStack.addEditProfilePane
+ }
+ }
+
+ onClicked: function openClick(handle) {
+ gcd.broadcast("ResetMessagePane");
+ gcd.broadcast("ResetProfile");
+ gcd.selectedProfile = handle
+ gcd.loadProfile(handle)
+ parentStack.pane = parentStack.profilePane
+ }
+}
\ No newline at end of file