From 46ed17eec26a6860a3a49719b91ca59b80b3ff55 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Fri, 20 Nov 2020 11:42:29 -0800 Subject: [PATCH] gcd.torStatus; now peers get networkStatus, save as local attr, and pass to profilerow/myprofile to show online --- go.mod | 2 +- go.sum | 2 ++ go/constants/attributes.go | 3 ++ go/handlers/appHandler.go | 14 ++++---- go/handlers/peerHandler.go | 14 ++++---- go/ui/gcd.go | 42 +++++++++++++----------- go/ui/manager.go | 13 ++++++-- main.go | 2 +- qml/const/Const.qml | 6 ++++ qml/panes/ProfileManagerPane.qml | 1 - qml/panes/ServerAddEditPane.qml | 38 +++++++++++----------- qml/widgets/ContactList.qml | 4 +-- qml/widgets/MyProfile.qml | 50 +++++++++++++++++++++++++++-- qml/widgets/ProfileList.qml | 19 +++++------ qml/widgets/ProfileRow.qml | 55 ++++++++++++++++++++++++++++++++ qml/widgets/Statusbar.qml | 27 ++++++---------- 16 files changed, 208 insertions(+), 84 deletions(-) diff --git a/go.mod b/go.mod index 4c094f2c..49a09577 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module cwtch.im/ui go 1.12 require ( - cwtch.im/cwtch v0.4.8 + cwtch.im/cwtch v0.4.9 git.openprivacy.ca/openprivacy/connectivity v1.3.2 git.openprivacy.ca/openprivacy/log v1.0.1 github.com/c-bata/go-prompt v0.2.3 // indirect diff --git a/go.sum b/go.sum index 4fb6bf08..10684e77 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,8 @@ cwtch.im/cwtch v0.4.7 h1:y8Roq1L1PAs0FkBDdk+7EUVLCHwyzl+dOEfVu4VX0Ic= cwtch.im/cwtch v0.4.7/go.mod h1:Mh7vQQ3z55+prpX6EuUkg4QNQkBACMoDcgCNBeAH2EY= cwtch.im/cwtch v0.4.8 h1:f/FIek3PkJMskLT+f7SpIjpjlp5hMspAnGguXC3SA8s= cwtch.im/cwtch v0.4.8/go.mod h1:Mh7vQQ3z55+prpX6EuUkg4QNQkBACMoDcgCNBeAH2EY= +cwtch.im/cwtch v0.4.9 h1:X/6r5rARHSEjk4h0ZPw9NA/oFa+XdWgih0zEdrier40= +cwtch.im/cwtch v0.4.9/go.mod h1:Mh7vQQ3z55+prpX6EuUkg4QNQkBACMoDcgCNBeAH2EY= cwtch.im/tapir v0.2.0 h1:7MkoR5+uEuPW34/O0GZRidnIjq/01Cfm8nl5IRuqpGc= cwtch.im/tapir v0.2.0/go.mod h1:xzzZ28adyUXNkYL1YodcHsAiTt3IJ8Loc29YVn9mIEQ= cwtch.im/tapir v0.2.1 h1:t1YJB9q5sV1A9xwiiwL6WVfw3dwQWLoecunuzT1PQtw= diff --git a/go/constants/attributes.go b/go/constants/attributes.go index 5e972ada..8219d608 100644 --- a/go/constants/attributes.go +++ b/go/constants/attributes.go @@ -9,3 +9,6 @@ const ShowBlocked = "show-blocked" const ProfileTypeV1DefaultPassword = "v1-defaultPassword" const ProfileTypeV1Password = "v1-userPassword" + +// PeerOnline stores state on if the peer believes it is online +const PeerOnline = "peer-online" diff --git a/go/handlers/appHandler.go b/go/handlers/appHandler.go index 42d9ea07..99619cba 100644 --- a/go/handlers/appHandler.go +++ b/go/handlers/appHandler.go @@ -45,8 +45,7 @@ func App(gcd *ui.GrandCentralDispatcher, subscribed chan bool, reloadingAccounts } else { statuscode = 3 } - - gcd.TorStatus(statuscode) + gcd.SetTorStatus(statuscode) case event.PeerError: // current only case @@ -81,18 +80,21 @@ func App(gcd *ui.GrandCentralDispatcher, subscribed chan bool, reloadingAccounts p.SetAttribute(attr.GetPublicScope(constants.Picture), ui.ImageToString(ui.NewImage(ui.RandomProfileImage(onion), ui.TypeImageDistro))) } + if e.Data[event.Status] != event.StorageRunning || e.Data[event.Created] == event.True { + p.SetAttribute(attr.GetLocalScope(constants.PeerOnline), event.False) + the.CwtchApp.AddPeerPlugin(onion, plugins.CONNECTIONRETRY) + the.CwtchApp.AddPeerPlugin(onion, plugins.NETWORKCHECK) + } + log.Infof("NewPeer for %v\n", onion) ui.AddProfile(gcd, onion) - the.CwtchApp.AddPeerPlugin(onion, plugins.CONNECTIONRETRY) - the.CwtchApp.AddPeerPlugin(onion, plugins.NETWORKCHECK) - incSubscribed := make(chan bool) go PeerHandler(onion, gcd.GetUiManager(p.GetOnion()), incSubscribed) <-incSubscribed // TODO: wait till ACN is 100 and online - if e.Data[event.Status] != "running" { + if e.Data[event.Status] != event.StorageRunning || e.Data[event.Created] == event.True { p.Listen() p.StartPeersConnections() if _, err := groups.ExperimentGate(gcd.GlobalSettings.Experiments); err == nil { diff --git a/go/handlers/peerHandler.go b/go/handlers/peerHandler.go index 826b7191..83ce5fa3 100644 --- a/go/handlers/peerHandler.go +++ b/go/handlers/peerHandler.go @@ -2,6 +2,7 @@ package handlers import ( "cwtch.im/cwtch/app" + "cwtch.im/cwtch/app/plugins" "cwtch.im/cwtch/event" "cwtch.im/cwtch/model" "cwtch.im/cwtch/model/attr" @@ -38,19 +39,20 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) { subscribed <- true - networkOffline := false - for { e := q.Next() switch e.EventType { case event.NetworkStatus: - if e.Data["Status"] == "Success" && networkOffline { - networkOffline = false + online, _ := peer.GetAttribute(attr.GetLocalScope(constants.PeerOnline)) + if e.Data[event.Status] == plugins.NetworkCheckSuccess && online == event.False { + peer.SetAttribute(attr.GetLocalScope(constants.PeerOnline), event.True) + uiManager.UpdateNetworkStatus(true) // TODO we may have to reinitialize the peer - } else { - networkOffline = true + } else if e.Data[event.Status] == plugins.NetworkCheckError && online == event.True { + peer.SetAttribute(attr.GetLocalScope(constants.PeerOnline), event.False) + uiManager.UpdateNetworkStatus(false) } case event.NewMessageFromPeer: //event.TimestampReceived, event.RemotePeer, event.Data diff --git a/go/ui/gcd.go b/go/ui/gcd.go index c8bb2ccf..4850680d 100644 --- a/go/ui/gcd.go +++ b/go/ui/gcd.go @@ -36,25 +36,29 @@ type GrandCentralDispatcher struct { m_selectedProfile string m_selectedConversation string - _ string `property:"os"` - _ float32 `property:"themeScale,auto,changed"` - _ string `property:"theme,auto,changed"` - _ string `property:"locale,auto,changed"` - _ string `property:"version"` - _ string `property:"buildDate"` - _ string `property:"assetPath"` - _ string `property:"selectedProfile,auto"` - _ string `property:"selectedConversation,auto"` + _ string `property:"os"` + _ float32 `property:"themeScale,auto,changed"` + _ string `property:"theme,auto,changed"` + _ string `property:"locale,auto,changed"` + _ string `property:"version"` + _ string `property:"buildDate"` + _ string `property:"assetPath"` + _ string `property:"selectedProfile,auto"` + _ string `property:"selectedConversation,auto"` + + _ int `property:"torStatus"` + _ bool `property:experimentsEnabled,auto,changed` _ map[string]bool `property:experiments,auto,changed` // profile management stuff - _ func() `signal:"Loaded"` - _ func(handle, displayname, image, tag string) `signal:"AddProfile"` - _ func() `signal:"ErrorLoaded0"` - _ func() `signal:"ResetProfile"` - _ func() `signal:"ResetProfileList"` - _ func(failed bool) `signal:"ChangePasswordResponse"` + _ func() `signal:"Loaded"` + _ func(handle, displayname, image, tag string, online bool) `signal:"AddProfile"` + _ func() `signal:"ErrorLoaded0"` + _ func() `signal:"ResetProfile"` + _ func() `signal:"ResetProfileList"` + _ func(failed bool) `signal:"ChangePasswordResponse"` + _ func(onion string, online bool) `signal:"UpdateProfileNetworkStatus"` // server management _ func(handle, displayname, image string, status int, autostart bool, bundle string, messages int, key_types []string, keys []string) `signal:"AddServer"` @@ -83,8 +87,7 @@ type GrandCentralDispatcher struct { _ func(loading bool) `signal:"SetLoadingState"` // profile-area stuff - _ func(name, onion, image, tag, showBlocked string) `signal:"UpdateMyProfile"` - _ func(status int) `signal:"TorStatus"` + _ func(name, onion, image, tag, showBlocked string, online bool) `signal:"UpdateMyProfile"` // settings helpers _ func(str string) `signal:"InvokePopup"` @@ -749,7 +752,10 @@ func (this *GrandCentralDispatcher) loadProfile(onion string) { showBlocked = "false" the.Peer.SetAttribute(attr.GetSettingsScope(constants.ShowBlocked), showBlocked) } - this.UpdateMyProfile(the.Peer.GetName(), the.Peer.GetOnion(), getPicturePath(pic), tag, showBlocked) + + online, _ := the.Peer.GetAttribute(attr.GetLocalScope(constants.PeerOnline)) + + this.UpdateMyProfile(the.Peer.GetName(), the.Peer.GetOnion(), getPicturePath(pic), tag, showBlocked, online == event.True) contacts := the.Peer.GetContacts() for i := range contacts { diff --git a/go/ui/manager.go b/go/ui/manager.go index becad2f6..279d1520 100644 --- a/go/ui/manager.go +++ b/go/ui/manager.go @@ -2,6 +2,7 @@ package ui import ( "cwtch.im/cwtch/app" + "cwtch.im/cwtch/event" "cwtch.im/cwtch/model" "cwtch.im/cwtch/model/attr" "cwtch.im/cwtch/peer" @@ -187,8 +188,10 @@ func AddProfile(gcd *GrandCentralDispatcher, handle string) { tag, _ := p.GetAttribute(app.AttributeTag) - log.Infof("AddProfile %v %v %v %v\n", handle, nick, picPath, tag) - gcd.AddProfile(handle, nick, picPath, tag) + online, _ := p.GetAttribute(attr.GetLocalScope(constants.PeerOnline)) + + log.Infof("AddProfile %v %v %v %v %v\n", handle, nick, picPath, tag, online) + gcd.AddProfile(handle, nick, picPath, tag, online == event.True) } } @@ -220,6 +223,8 @@ type Manager interface { AboutToAddMessage() MessageJustAdded() StoreAndNotify(peer.CwtchPeer, string, string, time.Time, string) + + UpdateNetworkStatus(online bool) } // NewManager returns a new Manager interface for a profile to the gcd @@ -363,3 +368,7 @@ func (this *manager) UpdateContactAttribute(handle, key, value string) { func (this *manager) ChangePasswordResponse(error bool) { this.gcd.ChangePasswordResponse(error) } + +func (this *manager) UpdateNetworkStatus(online bool) { + this.gcd.UpdateProfileNetworkStatus(this.profile, online) +} diff --git a/main.go b/main.go index 6032c1bf..cd79e4b1 100644 --- a/main.go +++ b/main.go @@ -96,7 +96,7 @@ func main() { } log.ExcludeFromPattern("connection/connection") //log.ExcludeFromPattern("outbound/3dhauthchannel") - //log.AddNothingExceptFilter("event/eventmanager") + log.ExcludeFromPattern("event/eventmanager") log.ExcludeFromPattern("service.go") log.ExcludeFromPattern("tor/BaseOnionService.go") log.ExcludeFromPattern("applications/auth.go") diff --git a/qml/const/Const.qml b/qml/const/Const.qml index d7e09430..ef5aa014 100644 --- a/qml/const/Const.qml +++ b/qml/const/Const.qml @@ -22,5 +22,11 @@ Item { readonly property int state_failed: 5 readonly property int state_killed: 6 + // Tor statuses + readonly property int statusDisconnectedInternet: 0 + readonly property int statusDisconnectedTor: 1 + readonly property int statusConnecting: 2 + readonly property int statusOnline: 3 + } diff --git a/qml/panes/ProfileManagerPane.qml b/qml/panes/ProfileManagerPane.qml index a073f15d..f21ff010 100644 --- a/qml/panes/ProfileManagerPane.qml +++ b/qml/panes/ProfileManagerPane.qml @@ -58,7 +58,6 @@ ColumnLayout { id: "button" width: 100 * gcd.themeScale height: Theme.primaryTextSize * gcd.themeScale - icon: "lock_open-24px" //: Unlock text: qsTr("unlock") diff --git a/qml/panes/ServerAddEditPane.qml b/qml/panes/ServerAddEditPane.qml index 563ab79a..a35522b4 100644 --- a/qml/panes/ServerAddEditPane.qml +++ b/qml/panes/ServerAddEditPane.qml @@ -34,34 +34,34 @@ Opaque.SettingsList { // Add Profile Pane serverAddEditPane.server_messages = server_messages; } - settings: Column { + settings: Column { - anchors.horizontalCenter: parent.horizontalCenter - width: 700 + anchors.horizontalCenter: parent.horizontalCenter + width: 700 - Opaque.ScalingLabel { - text: server_name - size: 16 - } + Opaque.ScalingLabel { + text: server_name + size: 16 + } - Opaque.Setting { - label: qsTr("server-availability") + Opaque.Setting { + label: qsTr("server-availability") - field: Opaque.ToggleSwitch { - anchors.right: parent.right + field: Opaque.ToggleSwitch { + anchors.right: parent.right - isToggled: serverAddEditPane.server_available - onToggled: function() { - serverAddEditPane.server_available = !serverAddEditPane.server_available - if (serverAddEditPane.server_available) { - gcd.startServer(serverAddEditPane.server_name) - } else { - gcd.stopServer(serverAddEditPane.server_name) - } + isToggled: serverAddEditPane.server_available + onToggled: function() { + serverAddEditPane.server_available = !serverAddEditPane.server_available + if (serverAddEditPane.server_available) { + gcd.startServer(serverAddEditPane.server_name) + } else { + gcd.stopServer(serverAddEditPane.server_name) } } } + } diff --git a/qml/widgets/ContactList.qml b/qml/widgets/ContactList.qml index 92ac2120..193c674b 100644 --- a/qml/widgets/ContactList.qml +++ b/qml/widgets/ContactList.qml @@ -62,8 +62,8 @@ ColumnLayout { onTextChanged: { // TODO: detect peer or group address and insert a contactRow that asks to add the corresponding group or peer /*if (text != "") { - gcd.importString(text) - text = "" + gcd.importString(text) + text = "" }*/ } } diff --git a/qml/widgets/MyProfile.qml b/qml/widgets/MyProfile.qml index 0d0086d1..3fadc7a6 100644 --- a/qml/widgets/MyProfile.qml +++ b/qml/widgets/MyProfile.qml @@ -11,6 +11,7 @@ import "../opaque" as Opaque import "../opaque/styles" import "../opaque/theme" import "../opaque/fonts" +import "../const" Item { id: root @@ -25,6 +26,8 @@ Item { property string onion property string tag property bool dualPane: false + property bool profileOnline: false + property real logscale: 4 * Math.log10(gcd.themeScale + 1) @@ -99,7 +102,6 @@ Item { Rectangle { id: nameRow height: name.height - onWidthChanged: { name.textResize() } color: Theme.backgroundMainColor Rectangle { @@ -138,16 +140,60 @@ Item { } + function updateStatus() { + if (gcd.torStatus != Const.statusOnline) { // Tor network offline + portrait.portraitBorderColor = Theme.portraitOfflineBorderColor + portrait.portraitColor = Theme.portraitOfflineBackgroundColor + name.color = Theme.portraitOfflineTextColor + } else { + // TODO: update to include logic on if a peer wants to be online or not (not implemented) + + if (profileOnline == false) { + portrait.portraitBorderColor = Theme.portraitConnectingBorderColor + portrait.portraitColor = Theme.portraitConnectingBackgroundColor + name.color = Theme.portraitConnectingTextColor + } else { + portrait.portraitBorderColor = Theme.portraitOnlineBorderColor + portrait.portraitColor = Theme.portraitOnlineBackgroundColor + name.color = Theme.portraitOnlineTextColor + } + } + } + + Component.onCompleted: { updateStatus() } + Connections { target: gcd - onUpdateMyProfile: function(_nick, _onion, _image, _tag, _showBlocked) { + onUpdateMyProfile: function(_nick, _onion, _image, _tag, _showBlocked, _online) { nick = _nick onion = _onion image = _image tag = _tag + profileOnline = _online + updateStatus() } onResetProfile: { realignProfile() } + + onTorStatusChanged: function() { + updateStatus() + } + + onUpdateProfileNetworkStatus: function(_onion, online) { + if (onion == _onion) { + profileOnline = online + updateStatus() + } + } + + } + + Connections { + target: Theme + + onThemeChanged: { + updateStatus() + } } } diff --git a/qml/widgets/ProfileList.qml b/qml/widgets/ProfileList.qml index bcf4d0ef..204a1c8d 100644 --- a/qml/widgets/ProfileList.qml +++ b/qml/widgets/ProfileList.qml @@ -36,7 +36,7 @@ ColumnLayout { Connections { // ADD/REMOVE CONTACT ENTRIES target: gcd - onAddProfile: function(handle, displayName, image, tag) { + onAddProfile: function(handle, displayName, image, tag, online) { // don't add duplicates for (var i = 0; i < profilesModel.count; i++) { @@ -60,7 +60,7 @@ ColumnLayout { _displayName: displayName, _image: image, _tag: tag, - _status: 4, + _online: online, }) } @@ -93,16 +93,17 @@ ColumnLayout { image: _image tag: _tag Layout.fillWidth: true + profileOnline: _online rowClicked: function(handle) { - gcd.broadcast("ResetMessagePane"); - gcd.broadcast("ResetProfile"); - gcd.selectedProfile = handle; - gcd.loadProfile(handle); - parentStack.pane = parentStack.profilePane; + gcd.broadcast("ResetMessagePane"); + gcd.broadcast("ResetProfile"); + gcd.selectedProfile = handle; + gcd.loadProfile(handle); + parentStack.pane = parentStack.profilePane; } editClicked: function(handle, displayName, tag, image) { - profileAddEditPane.load(handle, displayName, tag, image); - parentStack.pane = parentStack.addEditProfilePane; + profileAddEditPane.load(handle, displayName, tag, image); + parentStack.pane = parentStack.addEditProfilePane; } } } diff --git a/qml/widgets/ProfileRow.qml b/qml/widgets/ProfileRow.qml index c058b01c..3e4af416 100644 --- a/qml/widgets/ProfileRow.qml +++ b/qml/widgets/ProfileRow.qml @@ -10,6 +10,8 @@ import QtQuick.Controls.Styles 1.4 import "../opaque" as Opaque import "../opaque/styles" import "../opaque/theme" +import "../const" + RowLayout { id: root @@ -20,6 +22,7 @@ RowLayout { property alias badgeColor: prow.badgeColor property var rowClicked: {} property var editClicked: {} + property bool profileOnline: false Opaque.PortraitRow { id: prow @@ -38,6 +41,54 @@ RowLayout { } onClicked: rowClicked(handle) + + function updateStatus() { + if (gcd.torStatus != Const.statusOnline) { // Tor network offline + portraitBorderColor = Theme.portraitOfflineBorderColor + portraitColor = Theme.portraitOfflineBackgroundColor + nameColor = Theme.portraitOfflineTextColor + onionColor = Theme.portraitOfflineTextColor + } else { + // TODO: update to include logic on if a peer wants to be online or not (not implemented) + + if (profileOnline == false) { + portraitBorderColor = Theme.portraitConnectingBorderColor + portraitColor = Theme.portraitConnectingBackgroundColor + nameColor = Theme.portraitConnectingTextColor + onionColor = Theme.portraitConnectingTextColor + } else { + portraitBorderColor = Theme.portraitOnlineBorderColor + portraitColor = Theme.portraitOnlineBackgroundColor + nameColor = Theme.portraitOnlineTextColor + onionColor = Theme.portraitOnlineTextColor + } + } + } + + Component.onCompleted: { prow.updateStatus() } + + Connections { + target: gcd + + onTorStatusChanged: function() { + prow.updateStatus() + } + + onUpdateProfileNetworkStatus: function(onion, online) { + if (handle == onion) { + profileOnline = online + prow.updateStatus() + } + } + } + + Connections { + target: Theme + + onThemeChanged: { + prow.updateStatus() + } + } } Opaque.Icon {// Edit BUTTON @@ -59,5 +110,9 @@ RowLayout { onClicked: editClicked(handle, displayName, tag, image) } + + + + } diff --git a/qml/widgets/Statusbar.qml b/qml/widgets/Statusbar.qml index 4a64bb8b..d1b60ed0 100644 --- a/qml/widgets/Statusbar.qml +++ b/qml/widgets/Statusbar.qml @@ -3,6 +3,8 @@ import QtQuick.Controls 2.4 import "../opaque" as Opaque import "../opaque/theme" +import "../const" + // Statusbar is a app wide 10-25 tall bar that should be place at the bottom of the app that gives network health information // it changes color and text/icon message based on network health. when netowrk is not healthy it is always in fullsized mode @@ -10,13 +12,6 @@ import "../opaque/theme" Rectangle { id: statusbar - property int status: statusDisconnectedInternet - - readonly property int statusDisconnectedInternet: 0 - readonly property int statusDisconnectedTor: 1 - readonly property int statusConnecting: 2 - readonly property int statusOnline: 3 - readonly property int openHeight: 25 readonly property int hideHeight: 10 @@ -59,7 +54,7 @@ Rectangle { } function changeStatus() { - if (status == statusDisconnectedInternet) { + if (gcd.torStatus == Const.statusDisconnectedInternet) { statusbar.color = Theme.statusbarDisconnectedInternetColor statusMessage.color = Theme.statusbarDisconnectedInternetFontColor networkStatus.iconColor = Theme.statusbarDisconnectedInternetFontColor @@ -69,7 +64,7 @@ Rectangle { //: Disconnected from the internet, check your connection statusMessage.text = qsTr("network-status-disconnected") show() - } else if (status == statusDisconnectedTor) { + } else if (gcd.torStatus == Const.statusDisconnectedTor) { statusbar.color = Theme.statusbarDisconnectedTorColor statusMessage.color = Theme.statusbarDisconnectedTorFontColor networkStatus.iconColor = Theme.statusbarDisconnectedTorFontColor @@ -79,7 +74,7 @@ Rectangle { //: Attempting to connect to Tor network statusMessage.text = qsTr("network-status-attempting-tor") show() - } else if (status == statusConnecting) { + } else if (gcd.torStatus == Const.statusConnecting) { statusbar.color = Theme.statusbarConnectingColor statusMessage.color = Theme.statusbarConnectingFontColor networkStatus.iconColor = Theme.statusbarConnectingFontColor @@ -150,7 +145,7 @@ Rectangle { } function resetHeight() { - if (isHover || status != statusOnline) { + if (isHover || gcd.torStatus != Const.statusOnline) { height = openHeight } else { height = hideHeight @@ -158,28 +153,26 @@ Rectangle { } function show() { - if (isHover || status != statusOnline) { + if (isHover || gcd.torStatus != Const.statusOnline) { hideAnim.stop() showAnim.start() } } function hide() { - if (!isHover && status == statusOnline) { + if (!isHover && gcd.torStatus == Const.statusOnline) { showAnim.stop() hideAnim.start() } } - onStatusChanged: { changeStatus() } - Component.onCompleted: { resetHeight(); changeStatus() } Connections { target: gcd - onTorStatus: function(code) { - status = code + onTorStatusChanged: function() { + changeStatus() } }