Using new cwtch attributes and get/ret val requests #272

Merged
sarah merged 1 commits from :keyval into master 2020-03-31 19:06:38 +00:00
11 changed files with 319 additions and 124 deletions

5
go.mod
View File

@ -3,11 +3,10 @@ module cwtch.im/ui
go 1.12
require (
cwtch.im/cwtch v0.3.10
cwtch.im/cwtch v0.3.11
git.openprivacy.ca/openprivacy/connectivity v1.1.1
git.openprivacy.ca/openprivacy/log v1.0.0
github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d // indirect
github.com/therecipe/qt v0.0.0-20191101232336-18864661ae4f
github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20191002095216-73192f6811d0 // indirect; Required - do not delete or `go tidy` away
golang.org/x/crypto v0.0.0-20200210222208-86ce3cb69678 // indirect
github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20191002095216-73192f6811d0 // indirect; Required - do not delete or `go tidy` away
)

17
go.sum
View File

@ -1,7 +1,11 @@
cwtch.im/cwtch v0.3.10 h1:akrIwsc1KnLbT3K6ZIFkhmA7kI62L03EWna7Ul1vszU=
cwtch.im/cwtch v0.3.10/go.mod h1:tmYeI2v0IEeBMbqzhcndXWZ2oyflhK4Afcf27+49rKU=
cwtch.im/cwtch v0.3.11 h1:2+W2w9HDQowKwEGx4oRLywmn0NzQ0Sg9JEyBdR/V1mA=
cwtch.im/cwtch v0.3.11/go.mod h1:PnMJb9CyzdrdbYjmL99pl6Nu34s6+lmeENVnGaY0hzk=
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=
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=
@ -12,6 +16,7 @@ git.openprivacy.ca/openprivacy/log v1.0.0/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQN
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
github.com/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca h1:Q2r7AxHdJwWfLtBZwvW621M3sPqxPc6ITv2j1FGsYpw=
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -36,6 +41,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
@ -44,6 +50,7 @@ github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0=
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0=
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@ -57,6 +64,7 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/struCoder/pidusage v0.1.3/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI=
github.com/therecipe/qt v0.0.0-20191101232336-18864661ae4f h1:06ICDSmDOBUC9jwgv44ngvyHzwudJNLa5H+rbCyDFRY=
github.com/therecipe/qt v0.0.0-20191101232336-18864661ae4f/go.mod h1:SUUR2j3aE1z6/g76SdD6NwACEpvCxb3fvG82eKbD6us=
@ -71,6 +79,8 @@ github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426
github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:mH55Ek7AZcdns5KPp99O0bg+78el64YCYWHiQKrOdt4=
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg=
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72 h1:+ELyKg6m8UBf0nPFSqD0mi7zUfwPyXo23HNjMnXPz7w=
@ -80,11 +90,15 @@ golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200210191831-6ca56c2f2e2b/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200210222208-86ce3cb69678 h1:wCWoJcFExDgyYx2m2hpHgwz8W3+FPdfldvIgzqDIhyg=
golang.org/x/crypto v0.0.0-20200210222208-86ce3cb69678/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200320181102-891825fb96df h1:lDWgvUvNnaTnNBc/dwOty86cFeKoKWbwy2wQj0gIxbU=
golang.org/x/crypto v0.0.0-20200320181102-891825fb96df/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200320181208-1c781a10960a h1:KaxWXSFrOaE2ptiOotI+zFdzHxBsg9MW6XfCv497IRo=
golang.org/x/net v0.0.0-20200320181208-1c781a10960a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -98,12 +112,15 @@ golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200320181252-af34d8274f85 h1:fD99hd4ciR6T3oPhr2EkmuKe9oHixHx9Hj/hND89j3g=
golang.org/x/sys v0.0.0-20200320181252-af34d8274f85/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190420181800-aa740d480789 h1:FF0rjo15h51+N6642mf5S3QuplmKo2aCrJUYkHTx85s=
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -1,9 +1,10 @@
package constants
const Nick = "nick"
const SchemaVersion = "schemaVersion"
const Name = "name"
const LastRead = "last-read"
const Picture = "picture"
const DefaultPassword = "default-password"
const ProfileTypeV1DefaultPassword = "v1-defaultPassword"
const ProfileTypeV1Password = "v1-userPassword"

View File

@ -1,5 +1,5 @@
package constants
const BlockUnknownPeersSetting = "settings.blockunknownpeers"
const LocaleSetting = "settings.locale"
const ZoomSetting = "settings.zoom"
const BlockUnknownPeersSetting = ".blockunknownpeers"
const LocaleSetting = ".locale"
const ZoomSetting = ".zoom"

View File

@ -91,10 +91,10 @@ func App(gcd *ui.GrandCentralDispatcher, subscribed chan bool, reloadingAccounts
}
case event.NewPeer:
onion := e.Data[event.Identity]
peer := the.CwtchApp.GetPeer(onion)
p := the.CwtchApp.GetPeer(onion)
if tag, exists := peer.GetAttribute(app.AttributeTag); !exists || tag == "" {
peer.SetAttribute(app.AttributeTag, constants.ProfileTypeV1DefaultPassword)
if tag, exists := p.GetAttribute(app.AttributeTag); !exists || tag == "" {
p.SetAttribute(app.AttributeTag, constants.ProfileTypeV1DefaultPassword)
}
log.Infof("NewPeer for %v\n", onion)
@ -104,16 +104,16 @@ func App(gcd *ui.GrandCentralDispatcher, subscribed chan bool, reloadingAccounts
the.CwtchApp.AddPeerPlugin(onion, plugins.NETWORKCHECK)
incSubscribed := make(chan bool)
go PeerHandler(onion, gcd.GetUiManager(peer.GetOnion()), incSubscribed)
go PeerHandler(onion, gcd.GetUiManager(p.GetOnion()), incSubscribed)
<-incSubscribed
if e.Data[event.Status] != "running" {
peer.Listen()
peer.StartPeersConnections()
peer.StartGroupConnections()
p.Listen()
p.StartPeersConnections()
p.StartGroupConnections()
}
blockUnkownPeers, exists := peer.GetAttribute(constants.BlockUnknownPeersSetting)
blockUnkownPeers, exists := p.GetAttribute(constants.BlockUnknownPeersSetting)
if exists && blockUnkownPeers == "true" {
the.EventBus.Publish(event.NewEvent(event.BlockUnknownPeers, map[event.Field]string{}))
}

View File

@ -3,16 +3,21 @@ package handlers
import (
"cwtch.im/cwtch/app"
"cwtch.im/cwtch/event"
"cwtch.im/cwtch/model/attr"
peerC "cwtch.im/cwtch/peer"
"cwtch.im/cwtch/protocol/connections"
"cwtch.im/ui/go/constants"
"cwtch.im/ui/go/the"
"cwtch.im/ui/go/ui"
"git.openprivacy.ca/openprivacy/log"
"strconv"
"time"
)
func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) {
peer := the.CwtchApp.GetPeer(onion)
upgradeSchema(peer)
eventBus := the.CwtchApp.GetEventBus(onion)
q := event.NewQueue()
eventBus.Subscribe(event.NewMessageFromPeer, q)
@ -27,6 +32,7 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) {
eventBus.Subscribe(event.NetworkStatus, q)
eventBus.Subscribe(event.ChangePasswordSuccess, q)
eventBus.Subscribe(event.ChangePasswordError, q)
eventBus.Subscribe(event.NewRetValMessageFromPeer, q)
subscribed <- true
@ -49,9 +55,6 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) {
case event.NewMessageFromPeer: //event.TimestampReceived, event.RemotePeer, event.Data
ts, _ := time.Parse(time.RFC3339Nano, e.Data[event.TimestampReceived])
uiManager.AddMessage(e.Data[event.RemotePeer], e.Data[event.RemotePeer], e.Data[event.Data], false, e.EventID, ts, true)
if peer.GetContact(e.Data[event.RemotePeer]) == nil {
peer.AddContact(e.Data[event.RemotePeer], e.Data[event.RemotePeer], false)
}
case event.PeerAcknowledgement:
uiManager.Acknowledge(e.Data[event.EventID])
@ -76,7 +79,7 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) {
cxnState := connections.ConnectionStateToType[e.Data[event.ConnectionState]]
// if it's not in the.PeerHandler it's new. Only add once Authed
if contact := peer.GetContact(e.Data[event.RemotePeer]); contact != nil {
if contact := peer.GetContact(e.Data[event.RemotePeer]); contact == nil {
// Contact does not exist, we will add them but we won't know who they are until they are authenticated
// So if we get any other state from an unknown contact we do nothing
// (the next exists check will fail)
@ -90,8 +93,27 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) {
if contact := peer.GetContact(e.Data[event.RemotePeer]); contact != nil {
contact.State = e.Data[event.ConnectionState]
uiManager.UpdateContactStatus(contact.Onion, int(cxnState), false)
if cxnState == connections.AUTHENTICATED {
peer.SendGetValToPeer(e.Data[event.RemotePeer], attr.PublicScope, constants.Name)
peer.SendGetValToPeer(e.Data[event.RemotePeer], attr.PublicScope, constants.Picture)
}
}
case event.NewRetValMessageFromPeer:
onion := e.Data[event.RemotePeer]
Outdated
Review

?

?
Outdated
Review

oph, reminder to myself i didnt delete after I filled the case:

oph, reminder to myself i didnt delete after I filled the case:
scope := e.Data[event.Scope]
path := e.Data[event.Path]
val := e.Data[event.Data]
exists, _ := strconv.ParseBool(e.Data[event.Exists])
if exists && scope == attr.PublicScope {
switch path {
case constants.Name:
uiManager.UpdateContactDisplayName(onion, val)
case constants.Picture:
uiManager.UpdateContactPicture(onion, val)
}
}
case event.ServerStateChange:
serverOnion := e.Data[event.GroupServer]
state := connections.ConnectionStateToType[e.Data[event.ConnectionState]]
@ -119,6 +141,72 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) {
case event.ChangePasswordError:
uiManager.ChangePasswordResponse(true)
}
}
}
func upgradeSchema(p peerC.CwtchPeer) {
schemaVerVal, exists := p.GetAttribute(constants.SchemaVersion)
if !exists {
schemaVerVal = "0"
}
schemaVer, err := strconv.Atoi(schemaVerVal)
if err != nil {
schemaVer = 0
}
if schemaVer < 1 {
upgradeSchema1(p)
}
}
func upgradeSchema1(p peerC.CwtchPeer) {
log.Infof("UpgradeSchema 1\n")
p.SetAttribute(attr.GetPublicScope(constants.Name), p.GetName())
if picture, exists := p.GetAttribute("picture"); exists {
p.SetAttribute(attr.GetPublicScope(constants.Picture), ui.ImageToString(ui.NewImage(picture, ui.TypeImageDistro)))
}
if locale, exists := p.GetAttribute("settings.locale"); exists {
p.SetAttribute(attr.GetSettingsScope(constants.LocaleSetting), locale)
}
if zoom, exists := p.GetAttribute("settings.zoom"); exists {
p.SetAttribute(attr.GetSettingsScope(constants.ZoomSetting), zoom)
}
if blockunknown, exists := p.GetAttribute("settings.blockunknownpeers"); exists {
p.SetAttribute(attr.GetSettingsScope(constants.BlockUnknownPeersSetting), blockunknown)
}
for _, contactID := range p.GetContacts() {
if nick, exists := p.GetContactAttribute(contactID, "nick"); exists {
p.SetContactAttribute(contactID, attr.GetLocalScope(constants.Name), nick)
}
if picture, exists := p.GetContactAttribute(contactID, "picture"); exists {
p.SetContactAttribute(contactID, attr.GetLocalScope(constants.Picture), ui.ImageToString(ui.NewImage(picture, ui.TypeImageDistro)))
}
if lastRead, exists := p.GetContactAttribute(contactID, "last-read"); exists {
p.SetContactAttribute(contactID, attr.GetLocalScope(constants.LastRead), lastRead)
}
}
for _, gID := range p.GetGroups() {
if nick, exists := p.GetGroupAttribute(gID, "nick"); exists {
p.SetGroupAttribute(gID, attr.GetLocalScope(constants.Name), nick)
}
if picture, exists := p.GetGroupAttribute(gID, "picture"); exists {
p.SetGroupAttribute(gID, attr.GetLocalScope(constants.Picture), ui.ImageToString(ui.NewImage(picture, ui.TypeImageDistro)))
}
if lastRead, exists := p.GetGroupAttribute(gID, "last-read"); exists {
p.SetGroupAttribute(gID, attr.GetLocalScope(constants.LastRead), lastRead)
}
}
p.SetAttribute(constants.SchemaVersion, "1")
}

View File

@ -3,6 +3,7 @@ package ui
import (
"cwtch.im/cwtch/app"
"cwtch.im/cwtch/event"
"cwtch.im/cwtch/model/attr"
"cwtch.im/cwtch/protocol/connections"
"cwtch.im/ui/go/constants"
"github.com/therecipe/qt/qml"
@ -49,6 +50,7 @@ type GrandCentralDispatcher struct {
// 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"`
@ -106,7 +108,6 @@ type GrandCentralDispatcher struct {
_ func() `signal:"requestPeerSettings,auto"`
_ func(onion, nick string) `signal:"savePeerSettings,auto"`
_ func(onion, groupID string) `signal:"inviteToGroup,auto"`
_ func(onion, key, nick string) `signal:"setAttribute,auto"`
_ func(onion string) `signal:"deleteContact,auto"`
_ func() `signal:"allowUnknownPeers,auto"`
_ func() `signal:"blockUnknownPeers,auto"`
@ -249,7 +250,7 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) {
this.UpdateContactStatus(group.GroupID, int(state), loading)
tl := group.GetTimeline()
nick, _ := group.GetAttribute(constants.Nick)
nick := getNick(handle)
updateLastReadTime(group.GroupID)
if nick == "" {
this.SetToolbarTitle(handle)
@ -264,7 +265,7 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) {
handle = tl[i].PeerID
}
name := getOrDefault(tl[i].PeerID, constants.Nick, tl[i].PeerID)
name := getNick(tl[i].PeerID)
image := getProfilePic(tl[i].PeerID)
this.PrependMessage(
@ -289,10 +290,7 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) {
var nick string
if contact != nil {
nick, _ = contact.GetAttribute(constants.Nick)
if nick == "" {
nick = handle
}
nick = getNick(contact.Onion)
}
updateLastReadTime(contact.Onion)
this.SetToolbarTitle(nick)
@ -306,7 +304,7 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) {
from = "me"
}
displayname := getOrDefault(messages[i].PeerID, constants.Nick, messages[i].PeerID)
displayname := getNick(messages[i].PeerID)
image := getProfilePic(messages[i].PeerID)
this.AppendMessage(
@ -325,9 +323,20 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) {
}
func (this *GrandCentralDispatcher) requestSettings() {
zoom, _ := the.Peer.GetAttribute(constants.ZoomSetting)
locale, _ := the.Peer.GetAttribute(constants.LocaleSetting)
blockunkownpeers, _ := the.Peer.GetAttribute(constants.BlockUnknownPeersSetting)
zoom, exists := the.Peer.GetAttribute(attr.GetSettingsScope(constants.ZoomSetting))
if !exists {
zoom = "1.0"
}
locale, exists := the.Peer.GetAttribute(attr.GetSettingsScope(constants.LocaleSetting))
Outdated
Review

I feel we need a better way of managing defaults than this.

I feel we need a better way of managing defaults than this.
Outdated
Review

we were doing nothing. open to suggestions. we don't really have a good handle yet on what our settings will ultimatly be, we need to work on our settings management some. Erinn has some ideas on this

we were doing nothing. open to suggestions. we don't really have a good handle yet on what our settings will ultimatly be, we need to work on our settings management some. Erinn has some ideas on this
if !exists {
// TODO: pull env locale
locale = ""
}
blockunkownpeers, exists := the.Peer.GetAttribute(attr.GetSettingsScope(constants.BlockUnknownPeersSetting))
if !exists {
blockunkownpeers = "false"
}
this.SupplySettings(zoom, locale, blockunkownpeers == "true")
}
@ -338,7 +347,7 @@ func (this *GrandCentralDispatcher) saveSettings(zoom, locale string) {
return
}
the.Peer.SetAttribute(constants.ZoomSetting, zoom)
the.Peer.SetAttribute(attr.GetSettingsScope(constants.ZoomSetting), zoom)
}
func (this *GrandCentralDispatcher) requestPeerSettings() {
@ -349,19 +358,13 @@ func (this *GrandCentralDispatcher) requestPeerSettings() {
return
}
name, exists := contact.GetAttribute(constants.Nick)
if !exists {
log.Errorf("error: couldn't find contact %v", this.SelectedConversation())
this.SupplyPeerSettings(this.SelectedConversation(), this.SelectedConversation(), contact.Blocked)
this.SupplyPeerSettings(this.SelectedConversation(), this.SelectedConversation(), contact.Blocked)
return
}
name := getNick(contact.Onion)
this.SupplyPeerSettings(contact.Onion, name, contact.Blocked)
}
func (this *GrandCentralDispatcher) savePeerSettings(onion, nick string) {
the.Peer.SetContactAttribute(onion, constants.Nick, nick)
the.Peer.SetContactAttribute(onion, attr.GetLocalScope(constants.Name), nick)
this.UpdateContactDisplayName(onion, nick)
}
@ -373,25 +376,21 @@ func (this *GrandCentralDispatcher) requestGroupSettings(groupID string) {
return
}
nick, _ := group.GetAttribute(constants.Nick)
nick := getNick(groupID)
invite, _ := the.Peer.ExportGroup(groupID)
contactaddrs := the.Peer.GetContacts()
contactnames := make([]string, len(contactaddrs))
for i, contact := range contactaddrs {
name, hasname := the.Peer.GetContact(contact).GetAttribute(constants.Nick)
if hasname {
contactnames[i] = name
} else {
contactnames[i] = contact
}
contactnames[i] = getNick(contact)
}
this.SupplyGroupSettings(group.GroupID, nick, group.GroupServer, invite, group.Accepted, contactnames, contactaddrs)
}
func (this *GrandCentralDispatcher) saveGroupSettings(groupID, nick string) {
the.Peer.SetGroupAttribute(groupID, constants.Nick, nick)
the.Peer.SetGroupAttribute(groupID, attr.GetLocalScope(constants.Name), nick)
this.UpdateContactDisplayName(groupID, nick)
}
@ -485,9 +484,10 @@ func (this *GrandCentralDispatcher) popup(str string) {
}
func (this *GrandCentralDispatcher) updateNick(onion, nick string) {
peer := the.CwtchApp.GetPeer(onion)
if peer != nil {
peer.SetName(nick)
p := the.CwtchApp.GetPeer(onion)
if p != nil {
p.SetName(nick)
p.SetAttribute(attr.GetPublicScope(constants.Name), nick)
the.CwtchApp.GetEventBus(onion).Publish(event.NewEvent(event.SetProfileName, map[event.Field]string{
event.ProfileName: nick,
}))
@ -503,7 +503,7 @@ func (this *GrandCentralDispatcher) createGroup(server, groupName string) {
this.GetUiManager(this.selectedProfile()).AddContact(groupID)
the.Peer.SetGroupAttribute(groupID, constants.Nick, groupName)
the.Peer.SetGroupAttribute(groupID, attr.GetLocalScope(constants.Name), groupName)
the.Peer.JoinServer(server)
}
@ -548,28 +548,23 @@ func (this *GrandCentralDispatcher) acceptGroup(groupID string) {
}
}
func (this *GrandCentralDispatcher) setAttribute(onion, key, value string) {
the.Peer.SetContactAttribute(onion, key, value)
this.GetUiManager(this.selectedProfile()).UpdateContactAttribute(onion, key, value)
}
func (this *GrandCentralDispatcher) blockUnknownPeers() {
the.Peer.SetAttribute(constants.BlockUnknownPeersSetting, "true")
the.Peer.SetAttribute(attr.GetSettingsScope(constants.BlockUnknownPeersSetting), "true")
the.EventBus.Publish(event.NewEvent(event.BlockUnknownPeers, map[event.Field]string{}))
}
func (this *GrandCentralDispatcher) allowUnknownPeers() {
the.Peer.SetAttribute(constants.BlockUnknownPeersSetting, "false")
the.Peer.SetAttribute(attr.GetSettingsScope(constants.BlockUnknownPeersSetting), "false")
the.EventBus.Publish(event.NewEvent(event.AllowUnknownPeers, map[event.Field]string{}))
}
func (this *GrandCentralDispatcher) setLocale(locale string) {
this.SetLocale_helper(locale)
the.Peer.SetAttribute(constants.LocaleSetting, locale)
the.Peer.SetAttribute(attr.GetSettingsScope(constants.LocaleSetting), locale)
zoom, _ := the.Peer.GetAttribute(constants.ZoomSetting)
blockunkownpeers, _ := the.Peer.GetAttribute(constants.BlockUnknownPeersSetting)
zoom, _ := the.Peer.GetAttribute(attr.GetSettingsScope(constants.ZoomSetting))
blockunkownpeers, _ := the.Peer.GetAttribute(attr.GetPeerScope(constants.BlockUnknownPeersSetting))
this.SupplySettings(zoom, locale, blockunkownpeers == "true")
}
@ -597,12 +592,17 @@ func (this *GrandCentralDispatcher) loadProfile(onion string) {
the.Peer = the.CwtchApp.GetPeer(onion)
the.EventBus = the.CwtchApp.GetEventBus(onion)
pic, exists := the.Peer.GetAttribute(constants.Picture)
picVal, exists := the.Peer.GetAttribute(attr.GetPublicScope(constants.Picture))
if !exists {
pic = RandomProfileImage(the.Peer.GetOnion())
the.Peer.SetAttribute(constants.Picture, pic)
picVal = ImageToString(NewImage(RandomProfileImage(onion), TypeImageDistro))
the.Peer.SetAttribute(attr.GetPublicScope(constants.Picture), picVal)
}
this.UpdateMyProfile(the.Peer.GetName(), the.Peer.GetOnion(), profilePicRelativize(pic))
pic, err := StringToImage(picVal)
if err != nil {
pic = NewImage(RandomProfileImage(onion), TypeImageDistro)
the.Peer.SetAttribute(attr.GetPublicScope(constants.Picture), ImageToString(pic))
}
this.UpdateMyProfile(the.Peer.GetName(), the.Peer.GetOnion(), getPicturePath(pic))
contacts := the.Peer.GetContacts()
for i := range contacts {
@ -617,7 +617,7 @@ func (this *GrandCentralDispatcher) loadProfile(onion string) {
// load ui preferences
this.RequestSettings()
locale, exists := the.Peer.GetAttribute(constants.LocaleSetting)
locale, exists := the.Peer.GetAttribute(attr.GetSettingsScope(constants.LocaleSetting))
if exists {
this.SetLocale_helper(locale)
}

34
go/ui/imageType.go Normal file
View File

@ -0,0 +1,34 @@
package ui
import "encoding/json"
// Image types we support
const (
Outdated
Review

wat? needs documentation

wat? needs documentation
// TypeImageDistro is a reletive path to any of the distributed images in cwtch/ui in the assets folder
TypeImageDistro = "distro"
// TypeImageComposition will be an face image composed of a recipe of parts like faceType, eyeType, etc
TypeImageComposition = "composition"
)
type image struct {
Val string
T string
}
func NewImage(val, t string) *image {
return &image{val, t}
}
func StringToImage(str string) (*image, error) {
var img image
err := json.Unmarshal([]byte(str), &img)
if err != nil {
return nil, err
}
return &img, nil
}
func ImageToString(img *image) string {
bytes, _ := json.Marshal(img)
return string(bytes)
}

View File

@ -3,6 +3,7 @@ package ui
import (
"cwtch.im/cwtch/app"
"cwtch.im/cwtch/model"
"cwtch.im/cwtch/model/attr"
"cwtch.im/cwtch/protocol/connections"
"cwtch.im/ui/go/constants"
"cwtch.im/ui/go/the"
@ -20,7 +21,7 @@ func isPeer(id string) bool {
return len(id) == 56
}
func getOrDefault(id, key, defaultVal string) string {
func getOrDefault(id, key string, defaultVal string) string {
var val string
var ok bool
if isGroup(id) {
@ -35,7 +36,7 @@ func getOrDefault(id, key, defaultVal string) string {
}
}
func getWithSetDefault(id string, key, defaultVal string) string {
func getWithSetDefault(id string, key string, defaultVal string) string {
var val string
var ok bool
if isGroup(id) {
@ -54,12 +55,34 @@ func getWithSetDefault(id string, key, defaultVal string) string {
return val
}
func getNick(id string) string {
if isGroup(id) {
nick, exists := the.Peer.GetGroupAttribute(id, attr.GetLocalScope(constants.Name))
if !exists || nick == "" {
nick, exists = the.Peer.GetGroupAttribute(id, attr.GetPeerScope(constants.Name))
if !exists {
nick = id
}
}
return nick
} else {
nick, exists := the.Peer.GetContactAttribute(id, attr.GetLocalScope(constants.Name))
if !exists {
nick, exists = the.Peer.GetContactAttribute(id, attr.GetPeerScope(constants.Name))
if !exists {
Outdated
Review

remove infos

remove infos
nick = id
}
}
Outdated
Review

and this one

and this one
return nick
}
}
// initLastReadTime checks and gets the Attributable's LastRead time or sets it to now
func initLastReadTime(id string) time.Time {
nowStr, _ := time.Now().MarshalText()
lastReadStr := getWithSetDefault(id, constants.LastRead, string(nowStr))
lastReadAttr := getWithSetDefault(id, attr.GetLocalScope(constants.LastRead), string(nowStr))
var lastRead time.Time
lastRead.UnmarshalText([]byte(lastReadStr))
lastRead.UnmarshalText([]byte(lastReadAttr))
return lastRead
}
@ -70,37 +93,57 @@ func profilePicRelativize(filename string) string {
return parts[len(parts)-1]
}
func initProfilePicture(id string) string {
// getProfilePic returns a string path to an image to display for hte given peer/group id
func getProfilePic(id string) string {
log.Debugf("getProfilePic for %v\n", id)
if isGroup(id) {
return profilePicRelativize(getWithSetDefault(id, constants.Picture, RandomGroupImage(id)))
if picVal, exists := the.Peer.GetGroupAttribute(id, attr.GetLocalScope(constants.Picture)); exists {
pic, err := StringToImage(picVal)
if err == nil {
return getPicturePath(pic)
Outdated
Review

remove overly verbose debug statements like this one

remove overly verbose debug statements like this one
}
}
if picVal, exists := the.Peer.GetGroupAttribute(id, attr.GetPeerScope(constants.Picture)); exists {
pic, err := StringToImage(picVal)
if err == nil {
return getPicturePath(pic)
}
}
return getPicturePath(NewImage(RandomGroupImage(id), TypeImageDistro))
} else {
return profilePicRelativize(getWithSetDefault(id, constants.Picture, RandomProfileImage(id)))
if picVal, exists := the.Peer.GetContactAttribute(id, attr.GetLocalScope(constants.Picture)); exists {
pic, err := StringToImage(picVal)
if err == nil {
return getPicturePath(pic)
}
}
if picVal, exists := the.Peer.GetContactAttribute(id, attr.GetPeerScope(constants.Picture)); exists {
pic, err := StringToImage(picVal)
if err == nil {
return getPicturePath(pic)
}
}
return getPicturePath(NewImage("fontawesome/regular/user.svg", TypeImageDistro))
}
}
// getProfilePic supplies a profile pic to use. In groups we may not have a contact so it will generate one
func getProfilePic(id string) string {
if isGroup(id) {
if pic, exists := the.Peer.GetGroupAttribute(id, constants.Picture); !exists {
return RandomGroupImage(id)
} else {
return profilePicRelativize(pic)
}
} else {
if pic, exists := the.Peer.GetContactAttribute(id, constants.Picture); !exists {
return profilePicRelativize(RandomProfileImage(id))
} else {
return pic
}
func getPicturePath(pic *image) string {
switch pic.T {
case TypeImageDistro:
return profilePicRelativize(pic.Val)
default:
log.Errorf("Unhandled profile picture type of %v\n", pic.T)
return ""
}
Outdated
Review

should be a switch statement with a default

should be a switch statement with a default
}
func updateLastReadTime(id string) {
lastRead, _ := time.Now().MarshalText()
if isGroup(id) {
the.Peer.SetGroupAttribute(id, constants.LastRead, string(lastRead))
the.Peer.SetGroupAttribute(id, attr.GetLocalScope(constants.LastRead), string(lastRead))
} else {
the.Peer.SetContactAttribute(id, constants.LastRead, string(lastRead))
the.Peer.SetContactAttribute(id, attr.GetLocalScope(constants.LastRead), string(lastRead))
}
}
@ -118,23 +161,27 @@ func countUnread(messages []model.Message, lastRead time.Time) int {
// AddProfile adds a new profile to the UI
func AddProfile(gcd *GrandCentralDispatcher, handle string) {
peer := the.CwtchApp.GetPeer(handle)
if peer != nil {
nick := peer.GetName()
if nick == "" {
p := the.CwtchApp.GetPeer(handle)
if p != nil {
nick, exists := p.GetAttribute(attr.GetPublicScope(constants.Name))
if !exists {
nick = handle
peer.SetAttribute(constants.Nick, nick)
}
pic, ok := peer.GetAttribute(constants.Picture)
picVal, ok := p.GetAttribute(attr.GetPublicScope(constants.Picture))
if !ok {
pic = RandomProfileImage(handle)
peer.SetAttribute(constants.Picture, pic)
picVal = ImageToString(NewImage(RandomProfileImage(handle), TypeImageDistro))
}
pic, err := StringToImage(picVal)
if err != nil {
pic = NewImage(RandomProfileImage(handle), TypeImageDistro)
}
picPath := getPicturePath(pic)
tag, _ := peer.GetAttribute(app.AttributeTag)
log.Infof("AddProfile %v %v %v %v\n", handle, nick, profilePicRelativize(pic), tag)
gcd.AddProfile(handle, nick, profilePicRelativize(pic), tag)
tag, _ := p.GetAttribute(app.AttributeTag)
log.Infof("AddProfile %v %v %v %v\n", handle, nick, picPath, tag)
gcd.AddProfile(handle, nick, picPath, tag)
}
}
@ -157,6 +204,7 @@ type Manager interface {
ReloadProfiles()
UpdateContactDisplayName(handle string, name string)
UpdateContactPicture(handle string, picVal string)
UpdateContactStatus(handle string, status int, loading bool)
UpdateContactAttribute(handle, key, value string)
@ -184,40 +232,32 @@ func getLastMessageTime(tl *model.Timeline) int {
}
// AddContact adds a new contact to the ui for this manager's profile
func (this *manager) AddContact(Handle string) {
func (this *manager) AddContact(handle string) {
this.gcd.DoIfProfile(this.profile, func() {
if isGroup(Handle) {
group := the.Peer.GetGroup(Handle)
if isGroup(handle) {
group := the.Peer.GetGroup(handle)
if group != nil {
lastRead := initLastReadTime(group.GroupID)
unread := countUnread(group.Timeline.GetMessages(), lastRead)
picture := initProfilePicture(Handle)
nick, exists := group.GetAttribute(constants.Nick)
if !exists {
nick = Handle
}
picture := getProfilePic(handle)
this.gcd.AddContact(Handle, nick, picture, group.GroupServer, unread, int(connections.ConnectionStateToType[group.State]), false, false, getLastMessageTime(&group.Timeline))
this.gcd.AddContact(handle, getNick(handle), picture, group.GroupServer, unread, int(connections.ConnectionStateToType[group.State]), false, false, getLastMessageTime(&group.Timeline))
}
return
} else if !isPeer(Handle) {
log.Errorf("sorry, unable to handle AddContact(%v)", Handle)
} else if !isPeer(handle) {
log.Errorf("sorry, unable to handle AddContact(%v)", handle)
debug.PrintStack()
return
}
contact := the.Peer.GetContact(Handle)
contact := the.Peer.GetContact(handle)
if contact != nil {
lastRead := initLastReadTime(contact.Onion)
unread := countUnread(contact.Timeline.GetMessages(), lastRead)
picture := initProfilePicture(Handle)
nick, exists := contact.GetAttribute(constants.Nick)
if !exists {
nick = Handle
}
picture := getProfilePic(handle)
this.gcd.AddContact(Handle, nick, 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))
}
})
}
@ -238,7 +278,7 @@ func (this *manager) AddSendMessageError(peer string, signature string, err stri
func (this *manager) AddMessage(handle string, from string, message string, fromMe bool, messageID string, timestamp time.Time, Acknowledged bool) {
this.gcd.DoIfProfile(this.profile, func() {
nick := getOrDefault(handle, constants.Nick, handle)
nick := getNick(handle)
image := getProfilePic(handle)
// If we have this group loaded already
@ -270,6 +310,16 @@ func (this *manager) UpdateContactDisplayName(handle string, name string) {
})
}
// UpdateContactPicture updates a contact's picture in the contact list and conversations
func (this *manager) UpdateContactPicture(handle string, picVal string) {
this.gcd.DoIfProfile(this.profile, func() {
pic, err := StringToImage(picVal)
if err == nil {
this.gcd.UpdateContactPicture(handle, getPicturePath(pic))
}
})
}
// UpdateContactStatus updates a contact's status in the ui
func (this *manager) UpdateContactStatus(handle string, status int, loading bool) {
this.gcd.DoIfProfile(this.profile, func() {

View File

@ -25,13 +25,13 @@ Item {
id: mainImage
width: baseWidth
height: baseWidth
color: highlight ? windowItem.cwtch_dark_color: "#FFFFFF"
color: "#350052" //: "#FFFFFF" //windowItem.cwtch_dark_color: "#FFFFFF"
radius: width / 2
Rectangle {
width: highlight ? baseWidth - 4 : baseWidth
height: highlight ? baseWidth - 4 : baseWidth
color: button ? windowItem.cwtch_dark_color: "#FFFFFF"
color: "#350052" //: "#FFFFFF" // windowItem.cwtch_dark_color: "#FFFFFF"
radius: width / 2
anchors.centerIn:parent

View File

@ -244,6 +244,12 @@ Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
}
}
onUpdateContactPicture: function(_handle, _image) {
if (handle == _handle) {
image = _image
}
}
onIncContactUnreadCount: function(handle) {
if (handle == _handle && gcd.selectedConversation != handle) {
badge++