From 35cd963ec303ce4085e6849f569ce53e1c7a13e9 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Mon, 21 Sep 2020 14:31:45 -0700 Subject: [PATCH 1/2] Tapir Integtation II --- go.mod | 6 +- go.sum | 6 + go/handlers/appHandler.go | 1 - go/handlers/peerHandler.go | 2 +- go/ui/gcd.go | 62 ++++++++++- go/ui/manager.go | 11 +- main.go | 23 +++- qml/opaque | 2 +- qml/panes/GroupSettingsPane.qml | 191 ++++++++++++++++++++------------ qml/panes/OverlayPane.qml | 14 ++- qml/panes/ServerInfoPane.qml | 78 +++++++++++++ qml/widgets/ProfileList.qml | 2 + 12 files changed, 308 insertions(+), 90 deletions(-) create mode 100644 qml/panes/ServerInfoPane.qml diff --git a/go.mod b/go.mod index e71241b9..cfec9878 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,12 @@ module cwtch.im/ui go 1.12 require ( - cwtch.im/cwtch v0.3.16 - git.openprivacy.ca/openprivacy/connectivity v1.1.4 + cwtch.im/cwtch v0.4.0 + git.openprivacy.ca/openprivacy/connectivity v1.2.1 git.openprivacy.ca/openprivacy/log v1.0.1 github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d // indirect github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41 github.com/therecipe/qt/internal/binding/files/docs/5.12.0 v0.0.0-20200126204426-5074eb6d8c41 // indirect github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41 // indirect golang.org/x/crypto v0.0.0-20200420104511-884d27f42877 // indirect -) +) \ No newline at end of file diff --git a/go.sum b/go.sum index 127c46e7..103004b3 100644 --- a/go.sum +++ b/go.sum @@ -8,12 +8,16 @@ cwtch.im/cwtch v0.3.15 h1:Z7fFREwXY728q2YmmwgHL357zAobrsWJ2oPkkGwzvo0= cwtch.im/cwtch v0.3.15/go.mod h1:iI9q4C3njHFBYQkNEbzMdK6QWPS0Vbkc0FigRHZNTvM= cwtch.im/cwtch v0.3.16 h1:4M5So2zRDjy5byzd3G8ZrA2ZWObfm/oSIRfMBIFdOuI= cwtch.im/cwtch v0.3.16/go.mod h1:iI9q4C3njHFBYQkNEbzMdK6QWPS0Vbkc0FigRHZNTvM= +cwtch.im/cwtch v0.4.0 h1:lhGQiYRBqSF0Pif9QttYVL4B1Oy1vc0v3cZejL7c7x4= +cwtch.im/cwtch v0.4.0/go.mod h1:EvZQDbvXNu38m785dWF0MMljqJzwWrNTFT40HvoEAhI= cwtch.im/tapir v0.1.15 h1:XSCWOvjmNkzMT2IceFgTBXWGKtYfr3a8o+La1s10OhE= cwtch.im/tapir v0.1.15/go.mod h1:HzezugpEx+nZ3LdyDsl0w6n45IJYnOt8uqldkLWmaqs= cwtch.im/tapir v0.1.17 h1:2jVZUe1a88tMI4aJPvRTO4Id3NN3PsM62cT5lntEChk= cwtch.im/tapir v0.1.17/go.mod h1:HzezugpEx+nZ3LdyDsl0w6n45IJYnOt8uqldkLWmaqs= cwtch.im/tapir v0.1.18 h1:Fs/jL9ZRyel/A1D/BYzIPEVQau8y5BJg44yA+GQDbSM= cwtch.im/tapir v0.1.18/go.mod h1:/IrAI6CBHfgzsfgRT8WHVb1P9fCCz7+45hfsdkKn8Zg= +cwtch.im/tapir v0.2.0 h1:7MkoR5+uEuPW34/O0GZRidnIjq/01Cfm8nl5IRuqpGc= +cwtch.im/tapir v0.2.0/go.mod h1:xzzZ28adyUXNkYL1YodcHsAiTt3IJ8Loc29YVn9mIEQ= git.openprivacy.ca/openprivacy/connectivity v1.1.0/go.mod h1:4P8mirZZslKbo2zBrXXVjgEdqGwHo/6qoFBwFQW6d6E= git.openprivacy.ca/openprivacy/connectivity v1.1.1 h1:hKxBOmxP7Jdu3K1BJ93mRtKNiWUoP6YHt/o2snE2Z0w= git.openprivacy.ca/openprivacy/connectivity v1.1.1/go.mod h1:4P8mirZZslKbo2zBrXXVjgEdqGwHo/6qoFBwFQW6d6E= @@ -25,6 +29,8 @@ git.openprivacy.ca/openprivacy/connectivity v1.1.4 h1:/I9epvNNjM8rR/q5y9Y63D9/aP git.openprivacy.ca/openprivacy/connectivity v1.1.4/go.mod h1:4P8mirZZslKbo2zBrXXVjgEdqGwHo/6qoFBwFQW6d6E= git.openprivacy.ca/openprivacy/connectivity v1.2.0 h1:dbZ5CRl11vg3BNHdzRKSlDP8OUtDB+mf6FkxMVf73qw= git.openprivacy.ca/openprivacy/connectivity v1.2.0/go.mod h1:B7vzuVmChJtSKoh0ezph5vu6DQ0gIk0zHUNG6IgXCcA= +git.openprivacy.ca/openprivacy/connectivity v1.2.1 h1:oRL56TR9ZQnKkGkTIQ9wYbJ2IkOOsi/zLYExYiAS+sE= +git.openprivacy.ca/openprivacy/connectivity v1.2.1/go.mod h1:B7vzuVmChJtSKoh0ezph5vu6DQ0gIk0zHUNG6IgXCcA= git.openprivacy.ca/openprivacy/libricochet-go v1.0.11 h1:C7QFFzG0p5XKu0zcOIdLGwEpA9uU0BceBM7CfVK5D40= git.openprivacy.ca/openprivacy/libricochet-go v1.0.11/go.mod h1:yTMps/ZpYS+BNBBvANsNAft28FXrBvFHQauMYNWPrwE= git.openprivacy.ca/openprivacy/libricochet-go v1.0.13 h1:Z86uL9K47onznY1wP1P/wWfWMbbyvk6xnCp94R180os= diff --git a/go/handlers/appHandler.go b/go/handlers/appHandler.go index 851f0fc3..43414c91 100644 --- a/go/handlers/appHandler.go +++ b/go/handlers/appHandler.go @@ -87,7 +87,6 @@ func App(gcd *ui.GrandCentralDispatcher, subscribed chan bool, reloadingAccounts if e.Data[event.Status] != "running" { p.Listen() p.StartPeersConnections() - p.StartGroupConnections() } blockUnkownPeers, exists := p.GetAttribute(constants.BlockUnknownPeersSetting) diff --git a/go/handlers/peerHandler.go b/go/handlers/peerHandler.go index c4f940db..30637f95 100644 --- a/go/handlers/peerHandler.go +++ b/go/handlers/peerHandler.go @@ -127,7 +127,7 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) { if state == connections.AUTHENTICATED { loading = true } - uiManager.UpdateContactStatus(group.GroupID, int(state), loading) + uiManager.UpdateContactStatus(serverOnion, int(state), loading) } else { log.Errorf("found group that is nil :/") } diff --git a/go/ui/gcd.go b/go/ui/gcd.go index 3a855d0a..41f327b0 100644 --- a/go/ui/gcd.go +++ b/go/ui/gcd.go @@ -1,6 +1,7 @@ package ui import ( + "encoding/base64" "sync" "cwtch.im/cwtch/app" @@ -82,6 +83,7 @@ type GrandCentralDispatcher struct { _ func(locale string, zoom float32, theme string) `signal:"SupplySettings"` _ func(groupID, name, server, invitation string, accepted bool, addrbooknames, addrbookaddrs []string) `signal:"SupplyGroupSettings"` _ func(onion, nick string, authorization string, storage string) `signal:"SupplyPeerSettings"` + _ func(server string, key_types []string, keys []string) `signal:"SupplyServerSettings"` // signals emitted from the ui (written in go, below) // ui @@ -118,6 +120,8 @@ type GrandCentralDispatcher struct { _ func(onion string) `signal:"storeHistoryForPeer,auto"` _ func(onion string) `signal:"deleteHistoryForPeer,auto"` + _ func(handle string) `signal:"requestServerSettings,auto"` + _ func() `constructor:"init"` } @@ -380,6 +384,31 @@ func (this *GrandCentralDispatcher) deleteHistoryForPeer(onion string) { the.Peer.SetContactAttribute(onion, event.SaveHistoryKey, event.DeleteHistoryConfirmed) } +func (this *GrandCentralDispatcher) requestServerSettings(groupID string) { + group := the.Peer.GetGroup(groupID) + + if group == nil { + log.Errorf("couldn't find group %v", groupID) + return + } + + serverInfo := the.Peer.GetContact(group.GroupServer) + + key_types := []model.KeyType{model.KeyTypeServerOnion, model.KeyTypeTokenOnion, model.KeyTypePrivacyPass} + var keyNames []string + var keys []string + + for _, key_type := range key_types { + log.Debugf("Looking up %v %v", key_type, keyNames) + if key, has := serverInfo.GetAttribute(string(key_type)); has { + keyNames = append(keyNames, string(key_type)) + keys = append(keys, key) + } + } + + this.SupplyServerSettings(group.GroupServer, keyNames, keys) +} + func (this *GrandCentralDispatcher) requestGroupSettings(groupID string) { group := the.Peer.GetGroup(groupID) @@ -397,6 +426,9 @@ func (this *GrandCentralDispatcher) requestGroupSettings(groupID string) { contactnames[i] = getNick(contact) } this.SupplyGroupSettings(group.GroupID, nick, group.GroupServer, invite, group.Accepted, contactnames, contactaddrs) + status := connections.ConnectionStateToType[group.State] + log.Debugf("Sending New Group Status: %v %v", group.GroupServer, status) + this.UpdateContactStatus(group.GroupServer, int(status), false) } func (this *GrandCentralDispatcher) saveGroupSettings(groupID, nick string) { @@ -429,6 +461,29 @@ func (this *GrandCentralDispatcher) importString(str string) { return } + if strings.HasPrefix(str, "tofubundle:") { + bundle := strings.Split(str,"||") + this.importString(bundle[0][11:]) + this.importString(bundle[1]) + return + } + + // Server Key Bundles are prefixed with + if strings.HasPrefix(str, "server:") { + bundle, err := base64.StdEncoding.DecodeString(str[7:]) + if err == nil { + err := the.Peer.AddServer(string(bundle)) + if err == nil { + this.InvokePopup("Successfully Imported Server Key Bundle") + return + } + this.InvokePopup("Error Importing Server Key Bundle: " + err.Error()) + return + } + this.InvokePopup("Invalid Server Key Bundle: " + err.Error()) + return + } + log.Debugf("importing: %s\n", str) onion := str name := onion @@ -441,6 +496,7 @@ func (this *GrandCentralDispatcher) importString(str string) { this.InvokePopup("not a valid group invite") return } + return } @@ -650,7 +706,9 @@ func (this *GrandCentralDispatcher) loadProfile(onion string) { contacts := the.Peer.GetContacts() for i := range contacts { - this.GetUiManager(this.selectedProfile()).AddContact(contacts[i]) + if the.Peer.GetContact(contacts[i]).IsServer() == false { + this.GetUiManager(this.selectedProfile()).AddContact(contacts[i]) + } } groups := the.Peer.GetGroups() @@ -689,7 +747,7 @@ func (this *GrandCentralDispatcher) storeSetting(key, val string) { func (this *GrandCentralDispatcher) reloadProfileList() { this.ResetProfileList() - for onion, _ := range the.CwtchApp.ListPeers() { + for onion := range the.CwtchApp.ListPeers() { AddProfile(this, onion) } } diff --git a/go/ui/manager.go b/go/ui/manager.go index b88f70e1..6e991606 100644 --- a/go/ui/manager.go +++ b/go/ui/manager.go @@ -14,11 +14,18 @@ import ( ) func isGroup(id string) bool { - return len(id) == 32 + return len(id) == 32 && !isServer(id) } func isPeer(id string) bool { - return len(id) == 56 + return len(id) == 56 && !isServer(id) +} + +// Check if the id is associated with a contact with a KeyTypeServerOnion attribute (which indicates that this +// is a server, not a regular contact or a group +func isServer(id string) bool { + _, ok := the.Peer.GetContactAttribute(id, string(model.KeyTypeServerOnion)) + return ok } func getOrDefault(id, key string, defaultVal string) string { diff --git a/main.go b/main.go index b2b987a7..379cf270 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "cwtch.im/ui/go/ui" "cwtch.im/ui/go/ui/android" "flag" + "fmt" "git.openprivacy.ca/openprivacy/connectivity/tor" "git.openprivacy.ca/openprivacy/log" "github.com/therecipe/qt/androidextras" @@ -16,6 +17,8 @@ import ( "github.com/therecipe/qt/network" "github.com/therecipe/qt/qml" "github.com/therecipe/qt/quickcontrols2" + "io/ioutil" + "math/rand" "os" "os/user" "path" @@ -65,7 +68,7 @@ func main() { log.ExcludeFromPattern("service.go") log.ExcludeFromPattern("tor/BaseOnionService.go") log.ExcludeFromPattern("applications/auth.go") - log.ExcludeFromPattern("connections/engine.go") + //log.ExcludeFromPattern("connections/engine.go") if os.Getenv("CWTCH_FOLDER") != "" { the.CwtchDir = os.Getenv("CWTCH_FOLDER") @@ -233,10 +236,20 @@ func loadACN() { } var err error the.ACN, err = tor.NewTorACN(the.CwtchDir, torpath) - if err != nil { - // TODO: turn into UI error: status panel? - log.Errorf("Could not start Tor: %v", err) - os.Exit(1) + + if _, ok := err.(*tor.NoTorrcError); ok { + // Stopgap: just dump a basic torrc for now + port := rand.Intn(1000) + 9600 + controlPort := port + 1 + ioutil.WriteFile(path.Join(the.CwtchDir, "tor", "torrc"), []byte(fmt.Sprintf(`SOCKSPort %v \n ControlPort %v`, port, controlPort)), 0600) + the.ACN, err = tor.NewTorACNWithAuth(the.CwtchDir, torpath, controlPort, tor.NullAuthenticator{}) + + if err != nil { + // TODO: turn into UI error: status panel? + log.Errorf("Could not start Tor: %v", err) + os.Exit(1) + } + } } diff --git a/qml/opaque b/qml/opaque index e5e537c7..5c33d6ed 160000 --- a/qml/opaque +++ b/qml/opaque @@ -1 +1 @@ -Subproject commit e5e537c79bad4fa1c21a6544a1865287062bade3 +Subproject commit 5c33d6ed2c46f5fe039fc6fee3cb690cb562cb23 diff --git a/qml/panes/GroupSettingsPane.qml b/qml/panes/GroupSettingsPane.qml index d7ece6c2..f3dbb722 100644 --- a/qml/panes/GroupSettingsPane.qml +++ b/qml/panes/GroupSettingsPane.qml @@ -9,128 +9,177 @@ import QtQuick.Controls 1.4 import "../opaque" as Opaque import "../opaque/styles" import "../utils.js" as Utils +import "../opaque/theme" +import "../const" -ColumnLayout { // groupSettingsPane +Opaque.SettingsList { // groupSettingsPane id: gsp anchors.fill: parent property string groupID property variant addrbook + property bool connected: false + property bool synced: false - Flickable { + settings: Column { anchors.fill: parent - boundsBehavior: Flickable.StopAtBounds - clip:true - contentWidth: tehcol.width - contentHeight: tehcol.height - Column { - id: tehcol - width: gsp.width - leftPadding: 10 - spacing: 5 - - Opaque.ScalingLabel { - text: qsTr("server-label") + ":" - } - - TextField { - id: txtServer - style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 } - readOnly: true - } - - Opaque.Button { - icon: "regular/clipboard" - text: qsTr("copy-btn") + Opaque.Setting { + inline: false + label: qsTr("group-name-label") + field: Opaque.ButtonTextField { + id: txtGroupName + readOnly: false + button_text: qsTr("save-btn") + dropShadowColor: Theme.dropShadowPaneColor onClicked: { - gcd.popup("copied-clipboard-notification") + //: notification: copied to clipboard + gcd.saveGroupSettings(groupID, txtGroupName.text) + theStack.title = txtGroupName.text + } + } + } + + Opaque.Setting { + inline: false + label: qsTr("server-label") + + field: Opaque.ButtonTextField { + id: txtServer + readOnly: true + button_text: qsTr("copy-btn") + dropShadowColor: Theme.dropShadowPaneColor + onClicked: { + //: notification: copied to clipboard + gcd.popup(qsTr("copied-to-clipboard-notification")) txtServer.selectAll() txtServer.copy() } } + } - Opaque.ScalingLabel { - text: qsTr("invitation-label") + ":" - } + Opaque.Setting { + inline: false + label: qsTr("invitation-label") - TextField { + field: Opaque.ButtonTextField { id: txtInvitation - style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 } readOnly: true - } - - Opaque.Button { - icon: "regular/clipboard" - text: qsTr("copy-btn") - + button_text: qsTr("copy-btn") + dropShadowColor: Theme.dropShadowPaneColor onClicked: { - gcd.popup("copied-clipboard-notification") + //: notification: copied to clipboard + gcd.popup(qsTr("copied-to-clipboard-notification")) txtInvitation.selectAll() txtInvitation.copy() } } + } - Opaque.ScalingLabel{ - text: qsTr("group-name-label") + ":" - } + Opaque.Setting { + property color backgroundColor: parent.color + inline: true + label: qsTr("server-info") + field: Column { + width: parent.width + spacing:10 + RowLayout { + width: parent.width + Layout.fillWidth: true + Opaque.ScalingLabel { + text: gsp.connected ? qsTr("server-connectivity-connected") : qsTr("server-connectivity-disconnected") + Layout.alignment: Qt.AlignLeft + } + Opaque.Icon { + backgroundColor: Theme.backgroundPaneColor + id: serverStatusIcon + height: 18 + width: 18 + Layout.alignment: Qt.AlignRight + iconColor: gsp.connected ? Theme.statusbarOnlineFontColor : Theme.statusbarDisconnectedTorFontColor + source: gcd.assetPath + (gsp.connected ? "core/signal_cellular_4_bar-24px.svg" : "core/signal_cellular_connected_no_internet_4_bar-24px.svg") + } + } + RowLayout { + width: parent.width + Layout.fillWidth: true - TextField { - id: txtGroupName - style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 } - } + Opaque.ScalingLabel { + text: gsp.synced ? qsTr("server-synced") : qsTr("server-not-synced") + Layout.alignment: Qt.AlignLeft + } + Opaque.Icon { + id: serverSyncedStatusIcon + backgroundColor: Theme.backgroundPaneColor + height: 18 + width: 18 + Layout.alignment: Qt.AlignRight + iconColor : gsp.synced ? Theme.statusbarOnlineFontColor : Theme.statusbarConnectingFontColor + source: gcd.assetPath + (gsp.synced ? "core/syncing-01.svg" : "core/syncing-03.svg") + } + } - Opaque.Button { - text: qsTr("save-btn") + Opaque.Button { + icon: "regular/hdd" + text: qsTr("view-server-info") + anchors.right: parent.right - onClicked: { - gcd.saveGroupSettings(groupID, txtGroupName.text) - theStack.title = txtGroupName.text - theStack.pane = theStack.messagePane - } - } + onClicked: { + gcd.requestServerSettings(gcd.selectedConversation) + theStack.pane = theStack.serverInfoPane + } + } - //: Invite someone to the group - Opaque.ScalingLabel { text: qsTr("invite-to-group-label") } + } + } - ComboBox { - id: cbInvite - //popup.font.pixelSize: 12 - width: 200 - //font.pixelSize: 20 - style: CwtchComboBoxStyle{} - } - Opaque.Button { - text: qsTr("invite-btn") - onClicked: { - gcd.inviteToGroup(addrbook[cbInvite.currentIndex], groupID) - } - } + Column { + width:parent.width * 0.95 + anchors.horizontalCenter: parent.horizontalCenter Opaque.Button { icon: "regular/trash-alt" text: qsTr("delete-btn") + anchors.right: parent.right + onClicked: { gcd.leaveGroup(groupID) theStack.pane = theStack.emptyPane } } + } - }//end of column with padding - }//end of flickable + } Connections { target: gcd + onUpdateContactStatus: function(_handle, _status, _loading) { + if (txtServer.text == _handle) { + if (_status >= Const.state_connected) { + gsp.connected = true + serverStatusIcon + if (_status != Const.state_synced) { + gsp.synced = false + } else { + gsp.synced = true + } + } else { + gsp.connected = false + gsp.synced = false + } + } + } + onSupplyGroupSettings: function(gid, name, server, invite, accepted, addrbooknames, addrbookaddrs) { gsp.groupID = gid txtGroupName.text = name txtServer.text = server txtInvitation.text = invite - cbInvite.model = addrbooknames.map(function(e){return Utils.htmlEscaped(e)}) + //cbInvite.model = addrbooknames.map(function(e){return Utils.htmlEscaped(e)}) addrbook = addrbookaddrs } } diff --git a/qml/panes/OverlayPane.qml b/qml/panes/OverlayPane.qml index 293ebd96..911b0db1 100644 --- a/qml/panes/OverlayPane.qml +++ b/qml/panes/OverlayPane.qml @@ -33,10 +33,10 @@ ColumnLayout { //: Accept group invite button text: qsTr("accept-group-btn") icon: "regular/heart" - onClicked: { - gcd.acceptGroup(gcd.selectedConversation) - gcd.requestGroupSettings(gcd.selectedConversation) - } + onClicked: { + gcd.acceptGroup(gcd.selectedConversation) + gcd.requestGroupSettings(gcd.selectedConversation) + } } Opaque.Button { @@ -147,5 +147,11 @@ ColumnLayout { overlay.accepted = accepted overlay.inGroup = true } + + onSupplyServerSettings: function(server) { + overlay.name = server + } + + } } diff --git a/qml/panes/ServerInfoPane.qml b/qml/panes/ServerInfoPane.qml new file mode 100644 index 00000000..0ac3e10c --- /dev/null +++ b/qml/panes/ServerInfoPane.qml @@ -0,0 +1,78 @@ +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 QtQuick.Window 2.11 +import QtQuick.Controls 1.4 + +import "../opaque" as Opaque +import "../opaque/styles" +import "../utils.js" as Utils +import "../opaque/theme" +import "../const" + +Opaque.SettingsList { // groupSettingsPane + id: gsp + anchors.fill: parent + property string serverName + property color backgroundColor: parent.color + + settings: Column { + anchors.fill: parent + + Opaque.Setting { + inline: false + label: qsTr("server-label") + + field: Opaque.ButtonTextField { + id: txtServer + readOnly: true + text: serverName; + button_text: qsTr("copy-btn") + dropShadowColor: Theme.dropShadowPaneColor + onClicked: { + //: notification: copied to clipboard + gcd.popup(qsTr("copied-to-clipboard-notification")) + txtServer.selectAll() + txtServer.copy() + } + } + } + } + + Connections { + target: gcd + + onUpdateContactStatus: function(_handle, _status, _loading) { + if (txtServer.text == _handle) { + if (_status >= Const.state_connected) { + serverStatusIcon.iconColor = Theme.statusbarOnlineFontColor + serverStatusIcon.source = gcd.assetPath + "core/signal_cellular_4_bar-24px.svg" + if (_status != Const.state_synced) { + serverSyncedStatusIcon.iconColor = Theme.statusbarConnectingFontColor + serverSyncedStatusIcon.source = gcd.assetPath + "core/syncing-03.svg" + } else { + serverSyncedStatusIcon.iconColor = Theme.statusbarOnlineFontColor + serverSyncedStatusIcon.source = gcd.assetPath + "core/syncing-01.svg" + } + } else { + serverStatusIcon.iconColor = Theme.statusbarDisconnectedTorFontColor + serverStatusIcon.source = gcd.assetPath + "core/signal_cellular_connected_no_internet_4_bar-24px.svg" + serverSyncedStatusIcon.iconColor = Theme.statusbarDisconnectedTorFontColor + serverSyncedStatusIcon.source = gcd.assetPath + "core/syncing-03.svg" + } + } + } + + onSupplyServerSettings: function(server, key_names, keys) { + gsp.serverName = server; + toolbar.setTitle(qsTr("server-settings")); + console.log("Servers: " + key_names); + for (let i=0; i Date: Thu, 1 Oct 2020 14:37:15 -0700 Subject: [PATCH 2/2] Server Info Pane Fixups --- go.mod | 2 +- go.sum | 2 ++ i18n/translation_de.qm | Bin 3258 -> 3211 bytes i18n/translation_de.ts | 59 ++++++++++++++++++++++++++++------- i18n/translation_en.qm | Bin 7818 -> 8325 bytes i18n/translation_en.ts | 59 ++++++++++++++++++++++++++++------- i18n/translation_fr.qm | Bin 3170 -> 3125 bytes i18n/translation_fr.ts | 59 ++++++++++++++++++++++++++++------- i18n/translation_pt.qm | Bin 3004 -> 2923 bytes i18n/translation_pt.ts | 59 ++++++++++++++++++++++++++++------- qml/main.qml | 3 ++ qml/panes/ServerInfoPane.qml | 39 +++++++++++------------ 12 files changed, 213 insertions(+), 69 deletions(-) diff --git a/go.mod b/go.mod index cfec9878..7242b935 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module cwtch.im/ui go 1.12 require ( - cwtch.im/cwtch v0.4.0 + cwtch.im/cwtch v0.4.1 git.openprivacy.ca/openprivacy/connectivity v1.2.1 git.openprivacy.ca/openprivacy/log v1.0.1 github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d // indirect diff --git a/go.sum b/go.sum index 103004b3..f3b7ca5c 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ cwtch.im/cwtch v0.3.16 h1:4M5So2zRDjy5byzd3G8ZrA2ZWObfm/oSIRfMBIFdOuI= cwtch.im/cwtch v0.3.16/go.mod h1:iI9q4C3njHFBYQkNEbzMdK6QWPS0Vbkc0FigRHZNTvM= cwtch.im/cwtch v0.4.0 h1:lhGQiYRBqSF0Pif9QttYVL4B1Oy1vc0v3cZejL7c7x4= cwtch.im/cwtch v0.4.0/go.mod h1:EvZQDbvXNu38m785dWF0MMljqJzwWrNTFT40HvoEAhI= +cwtch.im/cwtch v0.4.1 h1:wjf/3Vw5fDByEwwnXqWrPtpKsXTLk0oz0PqNGYcR+MQ= +cwtch.im/cwtch v0.4.1/go.mod h1:EvZQDbvXNu38m785dWF0MMljqJzwWrNTFT40HvoEAhI= cwtch.im/tapir v0.1.15 h1:XSCWOvjmNkzMT2IceFgTBXWGKtYfr3a8o+La1s10OhE= cwtch.im/tapir v0.1.15/go.mod h1:HzezugpEx+nZ3LdyDsl0w6n45IJYnOt8uqldkLWmaqs= cwtch.im/tapir v0.1.17 h1:2jVZUe1a88tMI4aJPvRTO4Id3NN3PsM62cT5lntEChk= diff --git a/i18n/translation_de.qm b/i18n/translation_de.qm index 4e70a9993d8a916ccd9aff26196c503ec73b7fb7..371e5a8364da467ae9ee9152dca9bdce9795fee1 100644 GIT binary patch delta 302 zcmdlb*)2Iiq@IJ3?Zh7j2KF>Yo!x5~7#JfM*Iw3PU|{~oyz)y80|Q4q^BcAzp!jK) zeNTXVhKmrIrH$qDv2zRzEJs)`mY-o@;8tg=vF8KoGlS5aauAwpJ=^!aKyjvR5Sn8? zgyzy?pDvomz);V=o1>dsh=GA^0>=qEJD`DX5SsHn7f|T<`d7!a{%! z5#Wmv1o9cV_!8H@V-Nu9~;g-;_z`z*6xc0IRP`r+L z<(C=;297r7H*7^f@zX5(o&fm_7a=suT9(hp&H>GN&3du?3 z3Zc2Kv3=hQ6z4bwq3gLq*{6%<0WEyQ(akNyz`(YhBkUOQ@0jSTMyZA#6P+vKZ$n`fsbzKme*@$P+)IOjCzCdWsCZ2%*80k&Y_qIl<3^7#JG!T@>Op2$*wHolV`D9QW0QqWyoa6 zW5{7hWJqC1Wys?ITEM^t#9WzqWtk#bJmj)R2;V-SndT(t^$2tPbn|abjgz diff --git a/i18n/translation_de.ts b/i18n/translation_de.ts index a220c9f7..68ad72ff 100644 --- a/i18n/translation_de.ts +++ b/i18n/translation_de.ts @@ -69,44 +69,79 @@ GroupSettingsPane - + server-label Server - - + + copy-btn Kopieren + + copied-to-clipboard-notification + notification: copied to clipboard + in die Zwischenablage kopiert + + + invitation-label Einladung - + + server-info + + + + + server-connectivity-connected + + + + + server-connectivity-disconnected + + + + + server-synced + + + + + server-not-synced + + + + + view-server-info + + + + group-name-label Gruppenname - + save-btn Speichern - invite-to-group-label Invite someone to the group - In die Gruppe einladen + In die Gruppe einladen - invite-btn - Einladen + Einladen - + delete-btn Löschen @@ -454,13 +489,13 @@ - + your-profiles Your Profiles - + your-servers Your Profiles diff --git a/i18n/translation_en.qm b/i18n/translation_en.qm index a30481257968ad55dc545e143d491a64411b6ac9..a0a111b16aa4c6340d78c53f387bff5a608fcb9b 100644 GIT binary patch delta 1111 zcmZ`%YiJZ_6g@M$^VoUpBW`xnyt-A)sij_QBnq@%g0@1n5`obxm*=zRzWtQgyc_C0z>gl|<8PJb- zM&u0nd%Q=7d2hj>`yqYmy?ctpN?s}{i38z2Y1do3Sn!*4e$!bBxh9v3gA}?#-u#lE zLgu(=>~%5lh5X<<#>EpZ8ZWvSn5nEwvOXA7wil+z7gc&|a};`9IT_!{{?Y5o$i6LX zP^K1_hB?^*b$KXH#dYeMa5wLo+O8MSnHu%LwP8-WTkWf^2E1_>%~R^n7rlVg@0)x0 zIXY76i+9iw;a6X4uoZY>AMp+`O}tNx`&y$F#H+rckvlD%Xpisqeg>5HHP1kZjoUP1 z^)>+WwHaUi1o-Q<7k1E6Gop1R7txtY?QkuH=^tumG{%F+wFgHitZ=JuGC<^v@Z?Ye*x- z$3g-*o((Doh0M1sYh{|OOjRPCN?D1V-DKyQA6={l=bTisosgHBosbqRglvArzKN~?E8krhnYLaI?nn{wF xC<=`irP8^oY;!8%cCIiUCH}_ds{Sb$Xf#aKHPymPBv#L>Z8isyaZ%lt-bN&BQIDM+Mgp0wOq7Wf&%zXfVQL51 zrKhk9MPX_)G^YySFQ;jmBZ`UmWKD0X7mdwoUN~-&k1Tpk=eyac~A~ z1sB0QzS81AX{VIwXr{BNTj*I-0Ivq`$)yIjMIplF0B=8dw>If~{IzSwD6^ zuT5({2qjJ0`u1reeYUpeICje&(FQ-^j>ui|4p$2rZZeG6I X-=MMiZ|m3li&(4wH0KP|@Cxf+e|ppz diff --git a/i18n/translation_en.ts b/i18n/translation_en.ts index ec54d325..d5c4beda 100644 --- a/i18n/translation_en.ts +++ b/i18n/translation_en.ts @@ -157,44 +157,79 @@ Right-click to reset. GroupSettingsPane - + server-label Server - - + + copy-btn Copy + + copied-to-clipboard-notification + notification: copied to clipboard + Copied to Clipboard + + + invitation-label Invitation - + + server-info + Server Information + + + + server-connectivity-connected + Server Connected + + + + server-connectivity-disconnected + Server Disconnected + + + + server-synced + Synced + + + + server-not-synced + Out of Sync + + + + view-server-info + Server Info + + + group-name-label Group Name - + save-btn Save - invite-to-group-label Invite someone to the group - Invite to group + Invite to group - invite-btn - Invite + Invite - + delete-btn Delete @@ -546,13 +581,13 @@ Right-click to reset. 0 profiles loaded with that password - + your-profiles Your Profiles Your Profiles - + your-servers Your Profiles Your Servers diff --git a/i18n/translation_fr.qm b/i18n/translation_fr.qm index 18e4d8b3fd91435da6d328986e31ec817614e5e7..42e1df36cf2b6a7e640c4cff2a4dbca8740d16a2 100644 GIT binary patch delta 307 zcmaDPu~lM%NIeH5+lfC64D5D{I=j~}Ffc|juDz_oz`*>AdF7WH1_lmw<~M9bK=IQo z`zoOL1>P2 z2+etqeY$8K14BJ~HAgqM5Ca2S8OI4bJD`Cs5Snu~7f_F_mkgo=>loV J&39Q_*#J&oQ``Um delta 370 zcmdlg@knBVNWB1q*zFt!1{NNMg*J5z49q7O*-rdnU|>&X)Y-j;fq^lKaqVRtpm-hg z$}cqx3>-epZ`g`};-^{mJpu9=PC{swwJe{HodcTlmi1!!83qQfZ)`R8d<+as+aNS2 zJA~$HVEeuoD9+IXq3gMr*{6%<0WDm>(akNyz`!<}hoI9o40jQ6cyZA#6P+u&M$n`fsbv+Q8S&wJY)IOjCK0s(r2cCm} zKn~l@XA>3z6c^x&5j?{%nTt_~?S3W$1GnL3CB|J$lN-5}Cs(t)pRB+t$I6wNSC%<> zJ&U4^5`!m09zz*JCPN8BDnk*20z)A~DUg)|rqzM$JPx4U3~WFw3er`Qs#}t;n_iS( PS}^%Pi{j=i*3)bNLq1^2 diff --git a/i18n/translation_fr.ts b/i18n/translation_fr.ts index 000671df..abda02d8 100644 --- a/i18n/translation_fr.ts +++ b/i18n/translation_fr.ts @@ -69,44 +69,79 @@ GroupSettingsPane - + server-label Serveur - - + + copy-btn Copier + + copied-to-clipboard-notification + notification: copied to clipboard + Copié dans le presse-papier + + + invitation-label Invitation - + + server-info + + + + + server-connectivity-connected + + + + + server-connectivity-disconnected + + + + + server-synced + + + + + server-not-synced + + + + + view-server-info + + + + group-name-label Nom du groupe - + save-btn Sauvegarder - invite-to-group-label Invite someone to the group - Inviter quelqu'un + Inviter quelqu'un - invite-btn - Invitation + Invitation - + delete-btn Effacer @@ -454,13 +489,13 @@ - + your-profiles Your Profiles - + your-servers Your Profiles diff --git a/i18n/translation_pt.qm b/i18n/translation_pt.qm index a64ae3c57ba4483cab59cf3026bebce749cad26d..f0ec24706be7a09648130b9059bb25e1e9f6e956 100644 GIT binary patch delta 311 zcmdlZ{#tB;NIeH5+lfC63~UD&b#|{|U|>vOTzgrEfr0q|^U5zZ3=HhEncuJ#0mTop z?0W*_GhBtxEOsoPkDX&+U}<2zSbm0qfs2`~#-5LXf$0Z?<}iTJoZW2S_kzTiKxp>6 z5Sr7BeY$8K14BLAPmXSGA)o^|I8NBv0S#n<&>Vlcc+#f=Ewtt`n+bFn$1<*MUh9Ak zO5;xHb^xlc<1YS?!@$6Lj7Q}98=$%_2+dr;vuJ7`&;v#gnj@3v;2)p^Igjz#goOYd z!on9L2;?&g@g=T*$1qunk&DeN6X*e_&035rm?npC+D`t;EIxTTr}AWWR`JOXIMucCTSzU`$|Kdszo4p2NKI zOAS!`3G*AaBB1y|mVHlve1@wKnx&oP^RaUb3@j&EFP5KSVBqp$tFh-}U|?DTp*boc zH0Kqz?|Xsb9BL4{p0l2Px@aEIU?+}lZXpH+wm^;(c6LC6d?7Ta8y8RdRG>xHTxK(Y z4&r#vwasfCQ2l!Dlx_#0`s3WiA98>+Kaa@uH$Zh=5Sm$rXVKI?pabqfXpT)h2mgQ^ z#?NOH76KG!;foPG!!VhPQHZTR6DZ!jS&4B4)8sHt<;lXV;*b`= diff --git a/i18n/translation_pt.ts b/i18n/translation_pt.ts index 5f17bd16..349a5948 100644 --- a/i18n/translation_pt.ts +++ b/i18n/translation_pt.ts @@ -69,44 +69,79 @@ GroupSettingsPane - + server-label Servidor - - + + copy-btn Copiar + + copied-to-clipboard-notification + notification: copied to clipboard + Copiado + + + invitation-label Convite - + + server-info + + + + + server-connectivity-connected + + + + + server-connectivity-disconnected + + + + + server-synced + + + + + server-not-synced + + + + + view-server-info + + + + group-name-label Nome do Grupo - + save-btn Salvar - invite-to-group-label Invite someone to the group - Convidar ao grupo + Convidar ao grupo - invite-btn - Convidar + Convidar - + delete-btn Deletar @@ -454,13 +489,13 @@ - + your-profiles Your Profiles - + your-servers Your Profiles diff --git a/qml/main.qml b/qml/main.qml index 2073204a..8d3c3b30 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -215,6 +215,7 @@ ApplicationWindow { readonly property int userProfilePane: 2 readonly property int groupProfilePane: 3 readonly property int addGroupPane: 4 + readonly property int serverInfoPane: 5 Item { anchors.fill: parent } // empty @@ -235,6 +236,8 @@ ApplicationWindow { AddGroupPane { anchors.fill: parent } + ServerInfoPane { anchors.fill: parent } + onCurrentIndexChanged: { parentStack.updateToolbar() if (currentIndex == emptyPane) { diff --git a/qml/panes/ServerInfoPane.qml b/qml/panes/ServerInfoPane.qml index 0ac3e10c..31762287 100644 --- a/qml/panes/ServerInfoPane.qml +++ b/qml/panes/ServerInfoPane.qml @@ -17,6 +17,8 @@ Opaque.SettingsList { // groupSettingsPane anchors.fill: parent property string serverName property color backgroundColor: parent.color + property bool connected: false + property bool synced: false settings: Column { anchors.fill: parent @@ -44,32 +46,29 @@ Opaque.SettingsList { // groupSettingsPane Connections { target: gcd - onUpdateContactStatus: function(_handle, _status, _loading) { - if (txtServer.text == _handle) { - if (_status >= Const.state_connected) { - serverStatusIcon.iconColor = Theme.statusbarOnlineFontColor - serverStatusIcon.source = gcd.assetPath + "core/signal_cellular_4_bar-24px.svg" - if (_status != Const.state_synced) { - serverSyncedStatusIcon.iconColor = Theme.statusbarConnectingFontColor - serverSyncedStatusIcon.source = gcd.assetPath + "core/syncing-03.svg" - } else { - serverSyncedStatusIcon.iconColor = Theme.statusbarOnlineFontColor - serverSyncedStatusIcon.source = gcd.assetPath + "core/syncing-01.svg" - } - } else { - serverStatusIcon.iconColor = Theme.statusbarDisconnectedTorFontColor - serverStatusIcon.source = gcd.assetPath + "core/signal_cellular_connected_no_internet_4_bar-24px.svg" - serverSyncedStatusIcon.iconColor = Theme.statusbarDisconnectedTorFontColor - serverSyncedStatusIcon.source = gcd.assetPath + "core/syncing-03.svg" - } - } - } + onUpdateContactStatus: function(_handle, _status, _loading) { + if (txtServer.text == _handle) { + if (_status >= Const.state_connected) { + gsp.connected = true + serverStatusIcon + if (_status != Const.state_synced) { + gsp.synced = false + } else { + gsp.synced = true + } + } else { + gsp.connected = false + gsp.synced = false + } + } + } onSupplyServerSettings: function(server, key_names, keys) { gsp.serverName = server; toolbar.setTitle(qsTr("server-settings")); console.log("Servers: " + key_names); for (let i=0; i