diff --git a/go/gothings/gcd.go b/go/gothings/gcd.go index 5a94aa8..66486e5 100644 --- a/go/gothings/gcd.go +++ b/go/gothings/gcd.go @@ -35,6 +35,7 @@ type GrandCentralDispatcher struct { _ func() `signal:"ClearMessages"` _ func() `signal:"ResetMessagePane"` _ func(mID uint) `signal:"Acknowledged"` + _ func(title string) `signal:"SetToolbarTitle"` // profile-area stuff _ func(name, onion, image string) `signal:"UpdateMyProfile"` @@ -115,7 +116,14 @@ func (this *GrandCentralDispatcher) loadMessagesPane(handle string) { if len(handle) == 32 { // LOAD GROUP log.Debugf("LOADING GROUP %s", handle) - tl := the.Peer.GetGroup(handle).GetTimeline() + group := the.Peer.GetGroup(handle) + tl := group.GetTimeline() + nick, _ := group.GetAttribute("nick") + if nick == "" { + this.SetToolbarTitle(handle) + } else { + this.SetToolbarTitle(nick) + } log.Debugf("messages: %d", len(tl)) for i := range tl { if tl[i].PeerID == the.Peer.GetProfile().Onion { @@ -143,6 +151,14 @@ func (this *GrandCentralDispatcher) loadMessagesPane(handle string) { return } // ELSE LOAD CONTACT + contact, _ := the.Peer.GetProfile().GetContact(handle) + nick,_ := contact.GetAttribute("name") + if nick == "" { + this.SetToolbarTitle(handle) + } else { + this.SetToolbarTitle(nick) + } + messages := this.UIState.GetMessages(handle) for i := range messages { from := messages[i].From diff --git a/go/gothings/uistate.go b/go/gothings/uistate.go index 3e00ec5..c870d53 100644 --- a/go/gothings/uistate.go +++ b/go/gothings/uistate.go @@ -1,8 +1,6 @@ package gothings import ( - "cwtch.im/cwtch/event" - "cwtch.im/cwtch/model" "cwtch.im/ui/go/constants" "cwtch.im/ui/go/gobjects" "cwtch.im/ui/go/the" @@ -39,20 +37,7 @@ func (this *InterfaceState) AddContact(c *gobjects.Contact) { if the.Peer.GetContact(c.Handle) == nil { decodedPub, _ := base32.StdEncoding.DecodeString(strings.ToUpper(c.Handle)) - - pp := &model.PublicProfile{Name: c.DisplayName, Ed25519PublicKey: decodedPub[:32], Trusted: c.Trusted, Blocked: false, Onion: c.Handle, Attributes: make(map[string]string)} - pp.SetAttribute("name", c.DisplayName) - the.Peer.GetProfile().Contacts[c.Handle] = pp - if c.Trusted { - the.Peer.GetProfile().TrustPeer(c.Handle) - } - - the.CwtchApp.EventBus().Publish(event.NewEvent(event.SetPeerAttribute, map[event.Field]string{ - event.RemotePeer: c.Handle, - event.Key: "name", - event.Data: c.DisplayName, - })) - + the.Peer.AddContact(c.DisplayName, c.Handle, decodedPub, c.Trusted) go the.Peer.PeerWithOnion(c.Handle) } diff --git a/main.go b/main.go index d325ab9..20bf570 100644 --- a/main.go +++ b/main.go @@ -165,7 +165,6 @@ func loadCwtchData(gcd *gothings.GrandCentralDispatcher) { groups := the.Peer.GetGroups() for i := range groups { - log.Infof("adding saved group %v", groups[i]) group := the.Peer.GetGroup(groups[i]) group.NewMessage = make(chan model.Message) the.Peer.JoinServer(group.GroupServer) diff --git a/qml/main.qml b/qml/main.qml index 651703d..fa962ed 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -18,6 +18,10 @@ Item { readonly property real ratio: height / width + readonly property string cwtch_background_color: '#EEEEFF' + readonly property string cwtch_color: '#B09CBC' + readonly property string cwtch_dark_color: '#4B3557' + FontAwesome { // PRETTY BUTTON ICONS id: awesome resource: "qrc:/qml/fonts/fontawesome.ttf" @@ -138,10 +142,13 @@ Item { readonly property int groupProfilePane: 4 readonly property int addGroupPane: 5 + property string title + Item {} // empty OverlayPane { // messagePane + title: theStack.title anchors.fill: parent } @@ -202,5 +209,9 @@ Item { popup.visible = true anmPopup.restart() } + + onSetToolbarTitle: function(str) { + theStack.title = str + } } } \ No newline at end of file diff --git a/qml/overlays/BulletinOverlay.qml b/qml/overlays/BulletinOverlay.qml index d6679a8..75bfcff 100644 --- a/qml/overlays/BulletinOverlay.qml +++ b/qml/overlays/BulletinOverlay.qml @@ -2,15 +2,44 @@ import QtGraphicalEffects 1.0 import QtQuick 2.7 import QtQuick.Controls 2.4 import QtQuick.Controls.Material 2.0 +import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 + import "../widgets" import "../widgets/controls" as Awesome import "../fonts/Twemoji.js" as T +import "../utils.js" as Utils +import "../styles" ColumnLayout { Layout.fillWidth: true + width:parent.width + Text { + Layout.fillWidth: true + text: parent.toolbar.text + " Bulletin Board" + } + + TextField { + id: filter + + placeholderText: "Search.." + + style: CwtchTextFieldStyle{} + + anchors.left: parent.left + anchors.right: parent.right + + anchors.margins: 10 + + onTextChanged: { + bulletinView.filter = text + if (bulletinView.model.get(bulletinView.currentIndex).title.indexOf(text) == -1) { + bulletinView.currentIndex = -1 + } + } + } Flickable { // THE MESSAGE LIST ITSELF id: sv @@ -18,10 +47,9 @@ ColumnLayout { Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillHeight: true Layout.minimumWidth: parent.width - Layout.maximumWidth: parent.width Layout.fillWidth: true - contentWidth: colMessages.width - contentHeight: colMessages.height + contentWidth: bulletin.width + contentHeight: bulletin.height boundsBehavior: Flickable.StopAtBounds maximumFlickVelocity: 800 @@ -30,20 +58,28 @@ ColumnLayout { target: gcd onClearMessages: function() { - messagesModel.clear() + //jsonModel4.clear() } onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts) { - messagesModel.append({ - "_handle": handle, - "_from": from, - "_displayName": displayName, - "_message": parse(message, 12), - "_image": image, - "_mid": mid, - "_fromMe": fromMe, - "_ts": ts, - }) + var msg + try { + msg = JSON.parse(message) + } catch (e) { + return + } + if (msg.o != 2) return + + if (msg.t != undefined) { + jsonModel4.insert(0,{ + "title":msg.t, + "body": msg.b, + "selected":false, + "from": from, + "displayName": displayName, + "timestamp": ts + }) + } if (sv.contentY + sv.height >= sv.contentHeight - colMessages.height && sv.contentHeight > sv.height) { sv.contentY = sv.contentHeight - sv.height @@ -51,35 +87,158 @@ ColumnLayout { } } - ScrollBar.vertical: ScrollBar{ policy: ScrollBar.AlwaysOn } - ColumnLayout { - id: colMessages - width: sv.width + ListView { + id: bulletinView + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.topMargin: 10 + + width: parent.width - 50 + height: parent.height - 20 + orientation: Qt.Vertical + spacing: 10 + model: jsonModel4 + property string filter: "" + delegate: + + Item { + width: parent.width + height: title.indexOf(bulletinView.filter) >= 0 ? (selected ? texttitle.height + textbody.height + replybtn.height + 8 : texttitle.height * 2) : 0 + visible: title.indexOf(bulletinView.filter) >= 0 + + Column { + width: parent.width + + RowLayout { + Button { + text: selected ? "-" : "+" + style: CwtchExpandingButton{} + } + Text { + id: texttitle + text: '' + Utils.htmlEscaped(title) + ' by ' + from + "
" + timestamp + leftPadding: 10 + topPadding: 5 + bottomPadding:5 + color: windowItem.cwtch_dark_color + } + MouseArea { + anchors.fill: parent + onClicked: { + selected = !selected + bulletinView.currentIndex = index + } + + } + } + + Rectangle { + height: 1 + color: windowItem.cwtch_color + anchors { + left: parent.left + right: parent.right + } + } + + Text { + id: textbody + visible: selected + text: Utils.htmlEscaped(body) + wrapMode: TextEdit.Wrap + leftPadding: 10 + topPadding: 10 + width: parent.width - 50 + } + + SimpleButton { + id: replybtn + visible: selected + text: "reply" + anchors.right: parent.right + anchors.rightMargin:10 + onClicked: { + console.log("REPLYING!!!") + gcd.broadcast("ResetMessagePane") + theStack.pane = theStack.messagePane + gcd.loadMessagesPane(from) + overlayStack.overlay = overlayStack.chatOverlay + } + } + } + + } + + focus: true + onCurrentItemChanged: console.log(model.get(bulletinView.currentIndex).title + ' selected') - ListModel { // MESSAGE OBJECTS ARE STORED HERE ... - id: messagesModel - } - Item { height: 6 } + ListModel { + id: jsonModel4 + } + } + } - Repeater { // ... AND DISPLAYED HERE - model: messagesModel - delegate: Message { - handle: _handle - from: _from - displayName: _displayName - message: "bulletinbulletinbulletin" - image: _image - messageID: _mid - fromMe: _fromMe - timestamp: _ts + GroupBox { + title: qsTr("New Bulletin") + Layout.fillWidth: true + + RowLayout { + Layout.fillWidth: true + width: parent.width + ColumnLayout { + Layout.fillWidth: true + + + Text { + text: "Post a new Bulletin Post" + } + + TextField { + id: newposttitle + placeholderText: "Title.." + Layout.fillWidth: true + style: CwtchTextFieldStyle{} + } + + TextArea { + id: newpostbody + Layout.fillWidth: true + style: CwtchTextAreaStyle{} + } + + + SimpleButton { // SEND MESSAGE BUTTON + id: btnSend + icon: "regular/paper-plane" + text: "post" + anchors.right: parent.right + anchors.rightMargin: 2 + + property int nextMessageID: 1 + + onClicked: { + if (newposttitle.text != "" && newpostbody.text != "") { + var msg = JSON.stringify({"o":2, "t":newposttitle.text, "b":newpostbody.text}) + gcd.sendMessage(msg, nextMessageID++) + } + newposttitle.text = "" + newpostbody.text = "" + } } } } + } -} \ No newline at end of file + + + + + + +} diff --git a/qml/panes/OverlayPane.qml b/qml/panes/OverlayPane.qml index c8b83fd..ea5f74e 100644 --- a/qml/panes/OverlayPane.qml +++ b/qml/panes/OverlayPane.qml @@ -9,10 +9,12 @@ import "../overlays" ColumnLayout { Layout.fillWidth: true + property alias title: toolbar.text StackToolbar { - text: "open privacy exec" + id: toolbar + //text: "open privacy exec" aux.onClicked: { theStack.pane = gcd.currentOpenConversation.length == 32 ? theStack.groupProfilePane : theStack.userProfilePane diff --git a/qml/styles/CwtchExpandingButton.qml b/qml/styles/CwtchExpandingButton.qml new file mode 100644 index 0000000..cd19d25 --- /dev/null +++ b/qml/styles/CwtchExpandingButton.qml @@ -0,0 +1,21 @@ +import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 + +ButtonStyle { + background: Rectangle { + width:25 + height:25 + color: windowItem.cwtch_dark_color + border.color: windowItem.cwtch_color + } + + label: Text { + renderType: Text.NativeRendering + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + font.family: "Monospace" + font.pointSize: 8 + color: windowItem.cwtch_background_color + text: control.text + } +} \ No newline at end of file diff --git a/qml/styles/CwtchTextAreaStyle.qml b/qml/styles/CwtchTextAreaStyle.qml new file mode 100644 index 0000000..b65d6f4 --- /dev/null +++ b/qml/styles/CwtchTextAreaStyle.qml @@ -0,0 +1,8 @@ +import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 + + +TextAreaStyle { + textColor: "black" + backgroundColor: windowItem.cwtch_background_color +} \ No newline at end of file diff --git a/qml/styles/CwtchTextFieldStyle.qml b/qml/styles/CwtchTextFieldStyle.qml new file mode 100644 index 0000000..e2e61a0 --- /dev/null +++ b/qml/styles/CwtchTextFieldStyle.qml @@ -0,0 +1,14 @@ +import QtQuick.Controls.Styles 1.4 +import QtQuick 2.7 + + +TextFieldStyle { + textColor: "black" + background: Rectangle { + radius: 2 + implicitWidth: 100 + implicitHeight: 24 + color: windowItem.cwtch_background_color + border.color: windowItem.cwtch_color + } +} \ No newline at end of file