diff --git a/chatchannellistener.go b/chatchannellistener.go index 50eb77c..dcaa873 100644 --- a/chatchannellistener.go +++ b/chatchannellistener.go @@ -32,7 +32,11 @@ func (this *ChatChannelListener) OpenInbound() { } func (this *ChatChannelListener) ChatMessage(messageID uint32, when time.Time, message string) bool { - DeliverMessageToUI(this.rai.RemoteHostname, message, uint(messageID), false, when) + DeliverMessageToUI(this.rai.RemoteHostname, this.rai.RemoteHostname, "", message, uint(messageID), false, when) + go func() { + time.Sleep(time.Second) + peer.Save() + }() return true } diff --git a/gcd.go b/gcd.go index 3bd7c7c..f61dfe6 100644 --- a/gcd.go +++ b/gcd.go @@ -18,7 +18,7 @@ type GrandCentralDispatcher struct { currentOpenConversation string // messages pane stuff - _ func(from, message string, mID uint, ts string) `signal:"AppendMessage"` + _ func(from, message, displayname string, mID uint, ts, source string) `signal:"AppendMessage"` _ func() `signal:"ClearMessages"` _ func() `signal:"ResetMessagePane"` _ func(uint) `signal:"Acknowledged"` @@ -78,7 +78,7 @@ func (this *GrandCentralDispatcher) sendMessage(message string, mID uint) { default: } - DeliverMessageToUI(gcd.currentOpenConversation, message, mID, true, time.Now()) + DeliverMessageToUI(gcd.currentOpenConversation, gcd.currentOpenConversation, "", message, mID, true, time.Now()) } func (this *GrandCentralDispatcher) loadMessagesPane(onion string) { @@ -86,15 +86,27 @@ func (this *GrandCentralDispatcher) loadMessagesPane(onion string) { gcd.currentOpenConversation = onion gcd.SetUnread(onion, 0) - if len(onion) == 32 { // eg 48e7dcfc353e6d77da2c31d63654fd19 + if len(onion) == 32 { // LOAD GROUP log.Printf("LOADING GROUP %s", onion) tl := peer.GetGroup(onion).GetTimeline() log.Printf("messages: %d", len(tl)) for i := range tl { - gcd.AppendMessage(tl[i].PeerID, tl[i].Message, 0, tl[i].Timestamp.Format(TIME_FORMAT)) + var handle string + if tl[i].PeerID == peer.GetProfile().Onion { + handle = "me" + } else { + handle = tl[i].PeerID + } + var name string + var exists bool + name, exists = peer.GetProfile().GetCustomAttribute(tl[i].PeerID + "_name") + if !exists || name == "" { + name = tl[i].PeerID[:16] + "..." + } + gcd.AppendMessage(handle, tl[i].Message, name, 0, tl[i].Timestamp.Format(TIME_FORMAT), randomProfileImage(tl[i].PeerID)) } return - } + } // ELSE LOAD CONTACT _, exists := contactMgr[onion] if exists { // (if not, they haven't been accepted as a contact yet) @@ -106,7 +118,7 @@ func (this *GrandCentralDispatcher) loadMessagesPane(onion string) { if messages[i].FromMe { from = "me" } - gcd.AppendMessage(from, messages[i].Message, messages[i].MessageID, messages[i].Timestamp.Format(TIME_FORMAT)) + gcd.AppendMessage(from, messages[i].Message, "", messages[i].MessageID, messages[i].Timestamp.Format(TIME_FORMAT), randomProfileImage(onion)) } } } diff --git a/main.go b/main.go index 26b0e54..aaa27ba 100644 --- a/main.go +++ b/main.go @@ -52,21 +52,21 @@ type Message struct { Timestamp time.Time } -func DeliverMessageToUI(from, message string, mID uint, fromMe bool, ts time.Time) { - _, found := contactMgr[from] +func DeliverMessageToUI(handle, from, displayname, message string, mID uint, fromMe bool, ts time.Time) { + _, found := contactMgr[handle] if !found { - contactMgr[from] = &Contact{[]Message{}, 0, 0} + contactMgr[handle] = &Contact{[]Message{}, 0, 0} } - contactMgr[from].AddMessage(Message{from, message, fromMe, mID, ts}) - if gcd.currentOpenConversation == from { + contactMgr[handle].AddMessage(Message{from, message, fromMe, mID, ts}) + if gcd.currentOpenConversation == handle { if fromMe { from = "me" } - gcd.AppendMessage(from, message, mID, ts.Format(TIME_FORMAT)) + gcd.AppendMessage(from, message, displayname, mID, ts.Format(TIME_FORMAT), randomProfileImage(from)) } else { - contactMgr[from].Unread++ - gcd.SetUnread(from, contactMgr[from].Unread) + contactMgr[handle].Unread++ + gcd.SetUnread(handle, contactMgr[handle].Unread) } } @@ -83,7 +83,9 @@ func main() { quickcontrols2.QQuickStyle_SetStyle("Universe") view := quick.NewQQuickView(nil) view.SetResizeMode(quick.QQuickView__SizeRootObjectToView) - view.SetTitle("bounce") + view.SetMinimumHeight(280) + view.SetMinimumWidth(300) + view.SetTitle("cwtch") gcd = NewGrandCentralDispatcher(nil) view.RootContext().SetContextProperty("gcd", gcd) @@ -113,11 +115,12 @@ func groupPoller() { groups := peer.GetGroups() for i := range groups { group := peer.GetGroup(groups[i]) - log.Printf("setting group %s to status %d", groups[i], int(servers[group.GroupServer])) + //log.Printf("setting group %s to status %d", groups[i], int(servers[group.GroupServer])) gcd.SetConnectionStatus(groups[i], int(servers[group.GroupServer])) } } } + func presencePoller() { // TODO: make this subscribe-able in ricochet time.Sleep(time.Second * 4) for { @@ -181,8 +184,22 @@ func torStatusPoller() { func cwtchListener(groupID string, channel chan model.Message) { for { m := <-channel - log.Printf("GROUPMSG %s", m.Message) - DeliverMessageToUI(groupID, m.Message, 0, m.PeerID == peer.GetProfile().Onion, m.Timestamp) + log.Printf("GROUPMSG %s %s", m.Message, m.PeerID) + name := m.PeerID + if name == peer.GetProfile().Onion { + name = "me" + } else { + var exists bool // lol this is a golang antifeature + name, exists = peer.GetProfile().GetCustomAttribute(m.PeerID + "_name") + if !exists { + name = "" + } + } + if name == "" { + name = m.PeerID[:16] + "..." + } + DeliverMessageToUI(groupID, m.PeerID, name, m.Message, 0, m.PeerID == peer.GetProfile().Onion, m.Timestamp) + peer.Save() } } @@ -225,19 +242,20 @@ func andHisBlackAndWhiteCat(incomingMessages chan Message) { } func initialize(view *quick.QQuickView) { + log.Printf(os.Args[0]) //TODO: this section is ported over and has a lot of printf errors, need to show them in the ui var dirname, filename string - if os.Getenv("SENDAFRIEND_FOLDER") != "" { - dirname = os.Getenv("SENDAFRIEND_FOLDER") - filename = path.Join(dirname, "identity.private") + if os.Getenv("CWTCH_FOLDER") != "" { + dirname = os.Getenv("CWTCH_FOLDER") + filename = path.Join(dirname, "keep-this-file-private") } else { usr, err := user.Current() if err != nil { fmt.Printf("\nerror: could not load current user: %v\n", err) os.Exit(1) } - dirname = path.Join(usr.HomeDir, ".sendafriend") - filename = path.Join(dirname, "identity.private") + dirname = path.Join(usr.HomeDir, ".cwtch") + filename = path.Join(dirname, "keep-this-file-private") } os.MkdirAll(dirname, 0700) @@ -293,6 +311,11 @@ func initialize(view *quick.QQuickView) { // temporary until we do real picture selection func randomProfileImage(onion string) string { + //TODO: this is a hack, fix ever passing this in + if onion == "me" { + onion = peer.GetProfile().Onion + } + choices := []string{"001-centaur", "002-kraken", "003-dinosaur", "004-tree-1", "005-hand", "006-echidna", "007-robot", "008-mushroom", "009-harpy", "010-phoenix", "011-dragon-1", "012-devil", "013-troll", "014-alien", "015-minotaur", "016-madre-monte", "017-satyr", "018-karakasakozou", "019-pirate", "020-werewolf", "021-scarecrow", "022-valkyrie", "023-curupira", "024-loch-ness-monster", "025-tree", "026-cerberus", "027-gryphon", "028-mermaid", "029-vampire", "030-goblin", "031-yeti", "032-leprechaun", "033-medusa", "034-chimera", "035-elf", "036-hydra", "037-cyclops", "038-pegasus", "039-narwhal", "040-woodcutter", "041-zombie", "042-dragon", "043-frankenstein", "044-witch", "045-fairy", "046-genie", "047-pinocchio", "048-ghost", "049-wizard", "050-unicorn"} barr, err := base32.StdEncoding.DecodeString(strings.ToUpper(onion)) if err != nil || len(barr) != 35 { diff --git a/qml/main.qml b/qml/main.qml index 1c05f56..3925599 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -8,17 +8,18 @@ import "fonts/Twemoji.js" as T import "widgets" Item { + id: windowItem width: 525 height: 500 - id: root + readonly property real ratio: height / width - FontAwesome { + FontAwesome { // PRETTY BUTTON ICONS id: awesome resource: "qrc:/qml/fonts/fontawesome.ttf" } - function parse(text, size) { + function parse(text, size) { // REPLACE EMOJI WITH TAGS T.twemoji.base = "qrc:/qml/fonts/twemoji/" T.twemoji.ext = ".png" T.twemoji.size = "72x72" @@ -26,7 +27,7 @@ Item { return T.twemoji.parse(text) } - function restoreEmoji(text) { + function restoreEmoji(text) { // REPLACE TAGS WITH EMOJI var re = //g var arr var newtext = text @@ -42,7 +43,57 @@ Item { } - RowLayout { + /* Rectangle { // THE TOOLBAR + id: toolbar + anchors.top: parent.top + anchors.left: parent.left + width: ratio >= 0.92 ? parent.width : 70 + height: ratio >= 0.92 ? 70 : parent.height + color: "#4B3557" + + GridLayout { + width: parent.width + height: parent.height + columns: ratio >= 0.92 ? children.length : 1 + + + ContactPicture { + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + source: "qrc:/qml/images/profiles/001-centaur.png" + status: -2 + } + + ContactPicture { + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + source: "qrc:/qml/images/profiles/002-kraken.png" + status: -2 + } + + ContactPicture { + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + source: "qrc:/qml/images/profiles/003-dinosaur.png" + status: -2 + } + + ContactPicture { + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + source: "qrc:/qml/images/profiles/004-tree-1.png" + status: -2 + } + + ContactPicture { + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + source: "qrc:/qml/images/profiles/005-hand.png" + status: -2 + } + } + }*/ + + 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 @@ -50,8 +101,9 @@ Item { Rectangle { // THE LEFT PANE WITH TOOLS AND CONTACTS color: "#D2C0DD" Layout.fillHeight: true - Layout.minimumWidth: 200 - Layout.maximumWidth: 200 + Layout.minimumWidth: Layout.maximumWidth + Layout.maximumWidth: theStack.pane == theStack.emptyPane ? parent.width : 200 + visible: (ratio <= 1.08 && windowItem.width >= 500) || theStack.pane == theStack.emptyPane ContactList{ @@ -59,21 +111,79 @@ Item { } } - Rectangle { // THE RIGHT PANE WHERE THE MESSAGES GO + Rectangle { // THE RIGHT PANE WHERE THE MESSAGES AND STuFF GO color: "#EEEEFF" Layout.fillWidth: true Layout.fillHeight: true - MessageList{ + StackLayout { + id: theStack anchors.fill: parent + currentIndex: 0 + + property alias pane: theStack.currentIndex + readonly property int emptyPane: 0 + readonly property int messagePane: 1 + readonly property int settingsPane: 2 + readonly property int userProfilePane: 3 + readonly property int groupProfilePane: 4 + + + Item {} // empty + + MessageList { // messagePane + anchors.fill: parent + } + + ColumnLayout { // settingsPane + anchors.fill: parent + + + StackToolbar { + text: "Cwtch Settings" + aux.visible: false + } + + Label { text: "welcome to the global app settings page!" } + } + + ColumnLayout { // userProfilePane + anchors.fill: parent + + + StackToolbar { + text: "Settings for Sarah" + aux.visible: false + + back.onClicked: theStack.pane = theStack.messagePane + } + + Label { text: "per-user things like contact name and picture will be edited here" } + } + + Label { // groupProfilePane + font.pixelSize: 12 + text: "invite new people or change the group name here" + + + StackToolbar { text: "Group settings" } + } + + Label { // addGroupPane + font.pixelSize: 12 + text: "add a new group" + + + StackToolbar { text: "Create group" } + } } } } PropertyAnimation { id: anmPopup; easing.type: Easing.InQuart; duration: 7000; target: popup; property: "opacity"; to: 0; } - Rectangle { + Rectangle { // THE ERROR MESSAGE POPUP id: popup anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter @@ -96,7 +206,7 @@ Item { } - Connections { + Connections { // POPUPS ARE INVOKED BY GO FUNCS target: gcd onInvokePopup: function(str) { diff --git a/qml/widgets/Contact.qml b/qml/widgets/Contact.qml index 4bebd3e..f94f5a4 100644 --- a/qml/widgets/Contact.qml +++ b/qml/widgets/Contact.qml @@ -57,7 +57,7 @@ RowLayout { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY id: rectUnread anchors.right: parent.right height: 16 - width: childrenRect.width + 10 + width: lblUnread.width + 10 radius: 8 color: "#4B3557" visible: badge != "0" @@ -65,6 +65,7 @@ RowLayout { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY Label { + id: lblUnread anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter color: "#FFFFFF" @@ -82,6 +83,7 @@ RowLayout { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY onClicked: { gcd.broadcast("ResetMessagePane") isActive = true + theStack.pane = theStack.messagePane gcd.loadMessagesPane(onion) } @@ -108,7 +110,6 @@ RowLayout { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY } onSetConnectionStatus: function(foronion, x) { - if (foronion.length == 32) console.log(onion+" setting status "+x+" for contact "+foronion) if (onion == foronion) { status = x } diff --git a/qml/widgets/Contact.qmlc b/qml/widgets/Contact.qmlc deleted file mode 100644 index a383a26..0000000 Binary files a/qml/widgets/Contact.qmlc and /dev/null differ diff --git a/qml/widgets/ContactList.qmlc b/qml/widgets/ContactList.qmlc deleted file mode 100644 index 827f822..0000000 Binary files a/qml/widgets/ContactList.qmlc and /dev/null differ diff --git a/qml/widgets/ContactPicture.qml b/qml/widgets/ContactPicture.qml index eb37934..f158872 100644 --- a/qml/widgets/ContactPicture.qml +++ b/qml/widgets/ContactPicture.qml @@ -9,7 +9,6 @@ Item { id: imgProfile implicitWidth: 48 implicitHeight: 48 - anchors.left: parent.left anchors.margins: 5 property alias source: img.source diff --git a/qml/widgets/Message.qml b/qml/widgets/Message.qml index 2836270..d954c18 100644 --- a/qml/widgets/Message.qml +++ b/qml/widgets/Message.qml @@ -8,12 +8,18 @@ import "controls" as Awesome RowLayout { id: root - Layout.alignment: from == "me" ? Qt.AlignRight : Qt.AlignLeft + //Layout.alignment: from == "me" ? Qt.AlignRight : Qt.AlignLeft + anchors.left: from == "me" ? undefined : parent.left + anchors.right: from == "me" ? parent.right : undefined + height: Math.max(imgProfile.height, rectMessageBubble.height) property alias message: lbl.text property string from + property string displayname property int messageID property alias timestamp: ts.text + property alias source: imgProfile.source + property alias status: imgProfile.status Connections { @@ -27,15 +33,22 @@ RowLayout { } + ContactPicture { + id: imgProfile + anchors.left: parent.left + visible: from != "me" + } + Rectangle { // THIS IS JUST A PRETTY MESSAGE-HOLDING RECTANGLE - height: childrenRect.height + 3 - width: childrenRect.width + 6 + id: rectMessageBubble + height: lbl.height + ts.height + 4 + width: colMessageBubble.width + 6 color: from == "me" ? "#B09CBC" : "#4B3557" radius: 5 // the console will complain constantly about me setting these anchors, but qt only allows margins if they've been set to something // a kludge to fix this would be to have spacers before/after and set the widths according to the side they're on ^ea - anchors.left: from == "me" ? undefined : parent.left + anchors.left: from == "me" ? undefined : imgProfile.right //parent.left anchors.right: from == "me" ? parent.right : undefined anchors.leftMargin: 5 anchors.rightMargin: 9 @@ -43,6 +56,9 @@ RowLayout { ColumnLayout { + id: colMessageBubble + + Column { // combine these into one element or else childrenRect won't play nicely TextEdit { // this is used as a helper to calculate the message box width id: dummy @@ -63,18 +79,19 @@ RowLayout { font.pixelSize: 12 selectByMouse: true readOnly: true - width: dummy.width > root.parent.width - 70 ? root.parent.width - 70 : dummy.width + width: Math.min(dummy.width, root.parent.width - (imgProfile.visible ? imgProfile.width : 0) - 40) wrapMode: TextEdit.Wrap textFormat: Text.RichText } } RowLayout { + id: rowBottom anchors.left: parent.left anchors.right: parent.right - Label { + Label { // TIMESTAMP id: ts color: "#FFFFFF" font.pixelSize: 10 @@ -82,13 +99,15 @@ RowLayout { leftPadding: 10 } - Label { + Label { text: dummy.width+", "+root.width } + + Label { // MESSAGE ACKNOWLEDGMENT id: ack color: "#FFFFFF" font.pixelSize: 10 anchors.right: parent.right font.family: "FontAwesome" - text: from == "me" ? awesome.icons.fa_ellipsis_h : "" + text: from == "me" ? awesome.icons.fa_ellipsis_h : displayname } } } diff --git a/qml/widgets/Message.qmlc b/qml/widgets/Message.qmlc deleted file mode 100644 index a38dd1a..0000000 Binary files a/qml/widgets/Message.qmlc and /dev/null differ diff --git a/qml/widgets/MessageList.qml b/qml/widgets/MessageList.qml index f2f703a..0925827 100644 --- a/qml/widgets/MessageList.qml +++ b/qml/widgets/MessageList.qml @@ -11,7 +11,13 @@ ColumnLayout { Layout.fillWidth: true - Flickable { + StackToolbar { + text: "Sarah Jamie Lewis" + + aux.onClicked: theStack.pane = theStack.userProfilePane + } + + Flickable { // THE MESSAGE LIST ITSELF id: sv clip: true Layout.alignment: Qt.AlignLeft | Qt.AlignTop @@ -32,12 +38,14 @@ ColumnLayout { messagesModel.clear() } - onAppendMessage: function(from, message, mid, ts) { + onAppendMessage: function(from, message, displayname, mid, ts, source) { messagesModel.append({ "f": from, "m": parse(message, 12), + "d": displayname, "i": mid, - "t": ts + "t": ts, + "src": source }) if (sv.contentY + sv.height >= sv.contentHeight - colMessages.height && sv.contentHeight > sv.height) { @@ -67,8 +75,10 @@ ColumnLayout { delegate: Message { from: f message: m + displayname: d messageID: i timestamp: t + source: src } } } @@ -98,9 +108,7 @@ ColumnLayout { maximumFlickVelocity: 300 - ScrollBar.vertical: ScrollBar{ - policy: ScrollBar.AlwaysOn - } + ScrollBar.vertical: ScrollBar{} TextEdit { id: txtMessage @@ -116,7 +124,7 @@ ColumnLayout { Keys.onReturnPressed: { // CTRL+ENTER = LINEBREAK if (event.modifiers & Qt.ControlModifier) { - txtMessage.insert(txtMessage.cursorPosition, "\n") + txtMessage.insert(txtMessage.cursorPosition, "
") } else if (event.modifiers == Qt.NoModifier) { btnSend.clicked() } @@ -126,7 +134,7 @@ ColumnLayout { // while also stripping any other tag, including other images. // TODO: this probably breaks if people actually do want to paste html onTextChanged: { - console.log("onTextChanged()") + //console.log("onTextChanged()") // we're taking advantage of TextEdit.getText()'s parsing capability, which means occasionally // passing text into it to be filtered. this prevents recursive calls putting us into an @@ -137,7 +145,7 @@ ColumnLayout { return } - console.log("1: " + txtMessage.getText(0, txtMessage.text.length)) + //console.log("1: " + txtMessage.getText(0, txtMessage.text.length)) // convert tags back to their emoji form var nt = restoreEmoji(txtMessage.text) @@ -146,15 +154,15 @@ ColumnLayout { txtMessage.text = nt } - console.log("2: " + txtMessage.getText(0, txtMessage.text.length)) + //console.log("2: " + txtMessage.getText(0, txtMessage.text.length)) // strip all HTML tags var theText = txtMessage.getText(0, txtMessage.text.length) - console.log("3: " + theText) + //console.log("3: " + theText) // convert emoji back to tags nt = parse(theText, 10) - console.log("4: " + nt) + //console.log("4: " + nt) // if there were changes... if (nt != txtMessage.getText(0, txtMessage.text.length)) { diff --git a/qml/widgets/MessageList.qmlc b/qml/widgets/MessageList.qmlc deleted file mode 100644 index deb16e4..0000000 Binary files a/qml/widgets/MessageList.qmlc and /dev/null differ diff --git a/qml/widgets/MyProfile.qml b/qml/widgets/MyProfile.qml index e832e36..2e74c04 100644 --- a/qml/widgets/MyProfile.qml +++ b/qml/widgets/MyProfile.qml @@ -2,6 +2,7 @@ import QtGraphicalEffects 1.0 import QtQuick 2.7 import QtQuick.Controls 2.4 import QtQuick.Controls.Material 2.0 +import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.3 ColumnLayout { @@ -10,8 +11,8 @@ ColumnLayout { width: parent.width property alias image: imgProfileImg.source - property alias nick: lblNick.text - property alias onion: lblOnion.text + property string nick + property string onion Item{ height: 6 } @@ -93,23 +94,56 @@ ColumnLayout { } } - InplaceEditText { // USER NICKNAME - id: lblNick - anchors.horizontalCenter: parent.horizontalCenter - width: parent.width + //InplaceEditText { // USER NICKNAME + // id: lblNick + // anchors.horizontalCenter: parent.horizontalCenter + // width: parent.width + // + // onUpdated: { + // gcd.updateNick(lblNick.text) + // } + //} - onUpdated: { - gcd.updateNick(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 } } - // TODO: this doesnt quite fit everything :{ Label { // ONION ADDRESS id: lblOnion font.pixelSize: 6 Layout.fillWidth: true padding: 3 horizontalAlignment: Text.AlignHCenter + text: "This is your address. You can give it out to people!\n" + onion } RowLayout { // TOOLS FOR EDITING PROFILE @@ -121,7 +155,7 @@ ColumnLayout { visible: false } - IconButton { + IconButton { // COPY ONION ADDRESS BUTTON icon: awesome.icons.fa_clipboard label: "copy" @@ -133,20 +167,19 @@ ColumnLayout { } } - IconButton { + IconButton { // SETTINGS BUTTON icon: awesome.icons.fa_cog //label: "settings" - onClicked: gcd.popup("not yet implemented, sorry :(") + onClicked: theStack.pane = theStack.settingsPane } - IconButton { + IconButton { // SIGN OUT BUTTON icon: awesome.icons.fa_sign_out //label: "sign out" onClicked: { gcd.popup("not yet implemented, sorry :(") - console.log(parse("💜", 20)) } } } @@ -199,7 +232,7 @@ ColumnLayout { onUpdateMyProfile: function(_nick, _onion, _image) { nick = _nick - onion = "This is your address. You should give it out to people!\n" + _onion + onion = _onion image = _image } diff --git a/qml/widgets/MyProfile.qmlc b/qml/widgets/MyProfile.qmlc index acefdcf..da21d08 100644 Binary files a/qml/widgets/MyProfile.qmlc and b/qml/widgets/MyProfile.qmlc differ diff --git a/qml/widgets/StackToolbar.qml b/qml/widgets/StackToolbar.qml new file mode 100644 index 0000000..4ae957d --- /dev/null +++ b/qml/widgets/StackToolbar.qml @@ -0,0 +1,49 @@ +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 "controls" as Awesome +import "../fonts/Twemoji.js" as T + +Rectangle { // OVERHEAD BAR ON STACK PANE + id: toolbar + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + height: 28 + color: "#EDEDED" + + property alias text: lbl.text + property alias aux: btnAux + property alias back: btnBack + + + IconButton {// BACK BUTTON + id: btnBack + icon: awesome.icons.fa_arrow_circle_o_left + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 6 + visible: ratio >= 1.08 || windowItem.width < 500 + + onClicked: theStack.pane = theStack.emptyPane + } + + Label { // TEXT + id: lbl + font.pixelSize: 16 + text: "Sarah Jamie Lewis" + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + } + + IconButton { // COG BUTTON + id: btnAux + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 6 + icon: awesome.icons.fa_cog + } +} \ No newline at end of file