Experimental Gating + Server List Sketch
the build was successful
Details
the build was successful
Details
This commit is contained in:
parent
ada9dc7bb9
commit
bfb431cbaf
4
go.mod
4
go.mod
|
@ -16,4 +16,8 @@ require (
|
||||||
github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41
|
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.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
|
github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41 // indirect
|
||||||
|
go.etcd.io/bbolt v1.3.5 // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20201022231255-08b38378de70 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20201022201747-fb209a7c41cd // indirect
|
||||||
)
|
)
|
||||||
|
|
10
go.sum
10
go.sum
|
@ -1,3 +1,4 @@
|
||||||
|
cwtch.im v0.4.3 h1:3c//RcO0+YFqm0XOILq7ScsGgQsA4waLU1XAbQRH3n4=
|
||||||
cwtch.im/cwtch v0.4.2-0.20201008200820-a2c5a28e092d h1:CuqoPJdfmKqvGnZhQtrv/9YqTRei3t06AvCGrCmD3gU=
|
cwtch.im/cwtch v0.4.2-0.20201008200820-a2c5a28e092d h1:CuqoPJdfmKqvGnZhQtrv/9YqTRei3t06AvCGrCmD3gU=
|
||||||
cwtch.im/cwtch v0.4.2-0.20201008200820-a2c5a28e092d/go.mod h1:EvZQDbvXNu38m785dWF0MMljqJzwWrNTFT40HvoEAhI=
|
cwtch.im/cwtch v0.4.2-0.20201008200820-a2c5a28e092d/go.mod h1:EvZQDbvXNu38m785dWF0MMljqJzwWrNTFT40HvoEAhI=
|
||||||
cwtch.im/cwtch v0.4.2-0.20201016053957-1933fb703fb0 h1:8d2hJyb6qupb9wS6px3734Hy1aHOrtwk4fpM1z/o3Tg=
|
cwtch.im/cwtch v0.4.2-0.20201016053957-1933fb703fb0 h1:8d2hJyb6qupb9wS6px3734Hy1aHOrtwk4fpM1z/o3Tg=
|
||||||
|
@ -60,6 +61,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/struCoder/pidusage v0.1.3 h1:pZcSa6asBE38TJtW0Nui6GeCjLTpaT/jAnNP7dUTLSQ=
|
||||||
github.com/struCoder/pidusage v0.1.3/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI=
|
github.com/struCoder/pidusage v0.1.3/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI=
|
||||||
github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41 h1:yBVcrpbaQYJBdKT2pxTdlL4hBE/eM4UPcyj9YpyvSok=
|
github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41 h1:yBVcrpbaQYJBdKT2pxTdlL4hBE/eM4UPcyj9YpyvSok=
|
||||||
github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:SUUR2j3aE1z6/g76SdD6NwACEpvCxb3fvG82eKbD6us=
|
github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:SUUR2j3aE1z6/g76SdD6NwACEpvCxb3fvG82eKbD6us=
|
||||||
|
@ -70,6 +72,8 @@ github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg=
|
go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg=
|
||||||
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||||
|
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
||||||
|
go.etcd.io/bbolt v1.3.5/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-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-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
@ -80,6 +84,8 @@ golang.org/x/crypto v0.0.0-20200420104511-884d27f42877/go.mod h1:LzIPMQfyMNhhGPh
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI=
|
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI=
|
||||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
|
||||||
|
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||||
|
@ -93,6 +99,8 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY=
|
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb h1:mUVeFHoDKis5nxCAzoAi7E8Ghb86EXh/RK6wtvJIqRY=
|
||||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.0.0-20201022231255-08b38378de70 h1:Z6x4N9mAi4oF0TbHweCsH618MO6OI6UFgV0FP5n0wBY=
|
||||||
|
golang.org/x/net v0.0.0-20201022231255-08b38378de70/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/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=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
@ -111,6 +119,8 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ix
|
||||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201022201747-fb209a7c41cd h1:WgqgiQvkiZWz7XLhphjt2GI2GcGCTIZs9jqXMWmH+oc=
|
||||||
|
golang.org/x/sys v0.0.0-20201022201747-fb209a7c41cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package constants
|
||||||
|
|
||||||
|
import "cwtch.im/cwtch/event"
|
||||||
|
|
||||||
|
// The server manage defines its own events...
|
||||||
|
const (
|
||||||
|
ListServers = event.Type("ListServers")
|
||||||
|
)
|
|
@ -0,0 +1,57 @@
|
||||||
|
package servers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"cwtch.im/cwtch/event"
|
||||||
|
"cwtch.im/cwtch/server"
|
||||||
|
"cwtch.im/ui/go/constants"
|
||||||
|
"cwtch.im/ui/go/the"
|
||||||
|
"cwtch.im/ui/go/ui"
|
||||||
|
"git.openprivacy.ca/openprivacy/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ServerManager is responsible for managing user operated servers
|
||||||
|
type ServerManager struct {
|
||||||
|
servers map[string]server.Server
|
||||||
|
}
|
||||||
|
|
||||||
|
func LaunchServiceManager(gcd *ui.GrandCentralDispatcher) {
|
||||||
|
sm := new(ServerManager)
|
||||||
|
sm.Init(gcd)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (sm * ServerManager) Init(gcd *ui.GrandCentralDispatcher) {
|
||||||
|
sm.servers = make(map[string]server.Server)
|
||||||
|
|
||||||
|
q := event.NewQueue()
|
||||||
|
the.AppBus.Subscribe(constants.ListServers, q)
|
||||||
|
|
||||||
|
for {
|
||||||
|
e := q.Next()
|
||||||
|
|
||||||
|
switch e.EventType {
|
||||||
|
case constants.ListServers: {
|
||||||
|
sm.ListServers(gcd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Replace with details from actual hosted servers. Right now these values are used to sketch / test out the
|
||||||
|
// UI QML
|
||||||
|
func (sm * ServerManager) ListServers(gcd *ui.GrandCentralDispatcher) {
|
||||||
|
log.Debugf("Listing Servers...")
|
||||||
|
gcd.AddServer("Server 1","Server 1","server",0)
|
||||||
|
gcd.AddServer("Server 2","Server 2","server",4)
|
||||||
|
gcd.AddServer("Server 3","Server 3","server",4)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm * ServerManager) StartServer(handle string) {
|
||||||
|
// TODO Start the server with the given handle config
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm * ServerManager) StopServer(handle string) {
|
||||||
|
// TODO Stop the given server
|
||||||
|
}
|
37
go/ui/gcd.go
37
go/ui/gcd.go
|
@ -1,17 +1,16 @@
|
||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"cwtch.im/cwtch/app"
|
"cwtch.im/cwtch/app"
|
||||||
"cwtch.im/cwtch/event"
|
"cwtch.im/cwtch/event"
|
||||||
"cwtch.im/cwtch/model"
|
"cwtch.im/cwtch/model"
|
||||||
"cwtch.im/cwtch/model/attr"
|
"cwtch.im/cwtch/model/attr"
|
||||||
"cwtch.im/cwtch/protocol/connections"
|
"cwtch.im/cwtch/protocol/connections"
|
||||||
"cwtch.im/ui/go/constants"
|
"cwtch.im/ui/go/constants"
|
||||||
|
"encoding/base64"
|
||||||
"github.com/therecipe/qt/qml"
|
"github.com/therecipe/qt/qml"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"cwtch.im/ui/go/the"
|
"cwtch.im/ui/go/the"
|
||||||
"encoding/base32"
|
"encoding/base32"
|
||||||
|
@ -46,6 +45,8 @@ type GrandCentralDispatcher struct {
|
||||||
_ string `property:"assetPath"`
|
_ string `property:"assetPath"`
|
||||||
_ string `property:"selectedProfile,auto"`
|
_ string `property:"selectedProfile,auto"`
|
||||||
_ string `property:"selectedConversation,auto"`
|
_ string `property:"selectedConversation,auto"`
|
||||||
|
_ bool `property:experimentsEnabled,auto,changed`
|
||||||
|
_ map[string]bool `property:experiments,auto,changed`
|
||||||
|
|
||||||
// profile management stuff
|
// profile management stuff
|
||||||
_ func() `signal:"Loaded"`
|
_ func() `signal:"Loaded"`
|
||||||
|
@ -55,6 +56,10 @@ type GrandCentralDispatcher struct {
|
||||||
_ func() `signal:"ResetProfileList"`
|
_ func() `signal:"ResetProfileList"`
|
||||||
_ func(failed bool) `signal:"ChangePasswordResponse"`
|
_ func(failed bool) `signal:"ChangePasswordResponse"`
|
||||||
|
|
||||||
|
// server management
|
||||||
|
_ func(handle, displayname, image string, status int) `signal:"AddServer"`
|
||||||
|
_ func() `signal:"requestServers,auto"`
|
||||||
|
|
||||||
// contact list stuff
|
// contact list stuff
|
||||||
_ func(handle, displayName, image string, badge, status int, authorization string, loading bool, lastMsgTime int) `signal:"AddContact"`
|
_ func(handle, displayName, image string, badge, status int, authorization string, loading bool, lastMsgTime int) `signal:"AddContact"`
|
||||||
_ func(handle, displayName string) `signal:"UpdateContactDisplayName"`
|
_ func(handle, displayName string) `signal:"UpdateContactDisplayName"`
|
||||||
|
@ -130,6 +135,8 @@ func (this *GrandCentralDispatcher) init() {
|
||||||
this.GlobalSettings = ReadGlobalSettings()
|
this.GlobalSettings = ReadGlobalSettings()
|
||||||
this.SetThemeScale(this.GlobalSettings.Zoom)
|
this.SetThemeScale(this.GlobalSettings.Zoom)
|
||||||
this.SetTheme(this.GlobalSettings.Theme)
|
this.SetTheme(this.GlobalSettings.Theme)
|
||||||
|
this.SetExperimentsEnabled(this.GlobalSettings.ExperimentsEnabled)
|
||||||
|
this.SetExperiments(this.GlobalSettings.Experiments)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUiManager gets (and creates if required) a ui Manager for the supplied profile id
|
// GetUiManager gets (and creates if required) a ui Manager for the supplied profile id
|
||||||
|
@ -377,6 +384,12 @@ func (this *GrandCentralDispatcher) requestServerSettings(groupID string) {
|
||||||
this.SupplyServerSettings(group.GroupServer, keyNames, keys)
|
this.SupplyServerSettings(group.GroupServer, keyNames, keys)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *GrandCentralDispatcher) requestServers() {
|
||||||
|
the.AppBus.Publish(event.NewEvent(constants.ListServers, map[event.Field]string{
|
||||||
|
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
func (this *GrandCentralDispatcher) requestGroupSettings(groupID string) {
|
func (this *GrandCentralDispatcher) requestGroupSettings(groupID string) {
|
||||||
group := the.Peer.GetGroup(groupID)
|
group := the.Peer.GetGroup(groupID)
|
||||||
|
|
||||||
|
@ -631,6 +644,22 @@ func (this *GrandCentralDispatcher) themeScaleChanged(newThemeScale float32) {
|
||||||
WriteGlobalSettings(this.GlobalSettings)
|
WriteGlobalSettings(this.GlobalSettings)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Turn on/off global experiments
|
||||||
|
func (this *GrandCentralDispatcher) experimentsEnabledChanged(enabled bool) {
|
||||||
|
this.GlobalSettings.ExperimentsEnabled = enabled
|
||||||
|
log.Debugf("Experiments Enabled: %v %v", enabled, this.GlobalSettings.ExperimentsEnabled)
|
||||||
|
WriteGlobalSettings(this.GlobalSettings)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn on/off global experiments
|
||||||
|
func (this *GrandCentralDispatcher) experimentsChanged(experiments map[string]bool) {
|
||||||
|
for k, v := range experiments {
|
||||||
|
this.GlobalSettings.Experiments[k] = v
|
||||||
|
}
|
||||||
|
log.Debugf("Experiments: %v", experiments)
|
||||||
|
WriteGlobalSettings(this.GlobalSettings)
|
||||||
|
}
|
||||||
|
|
||||||
func (this *GrandCentralDispatcher) themeChanged(newTheme string) {
|
func (this *GrandCentralDispatcher) themeChanged(newTheme string) {
|
||||||
this.GlobalSettings.Theme = newTheme
|
this.GlobalSettings.Theme = newTheme
|
||||||
WriteGlobalSettings(this.GlobalSettings)
|
WriteGlobalSettings(this.GlobalSettings)
|
||||||
|
|
|
@ -16,10 +16,12 @@ const GlobalSettingsFilename = "ui.globals"
|
||||||
const saltFile = "SALT"
|
const saltFile = "SALT"
|
||||||
|
|
||||||
type GlobalSettings struct {
|
type GlobalSettings struct {
|
||||||
Zoom float32
|
Zoom float32
|
||||||
Locale string
|
Locale string
|
||||||
Theme string
|
Theme string
|
||||||
PreviousPid int64
|
PreviousPid int64
|
||||||
|
ExperimentsEnabled bool
|
||||||
|
Experiments map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultGlobalSettings = GlobalSettings{
|
var DefaultGlobalSettings = GlobalSettings{
|
||||||
|
@ -27,6 +29,8 @@ var DefaultGlobalSettings = GlobalSettings{
|
||||||
Locale: "en",
|
Locale: "en",
|
||||||
Theme: "light",
|
Theme: "light",
|
||||||
PreviousPid: -1,
|
PreviousPid: -1,
|
||||||
|
ExperimentsEnabled: false,
|
||||||
|
Experiments: make(map[string]bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitGlobalSettingsFile(directory string, password string) error {
|
func InitGlobalSettingsFile(directory string, password string) error {
|
||||||
|
@ -68,6 +72,7 @@ func ReadGlobalSettings() *GlobalSettings {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Could not parse global ui settings: %v\n", err)
|
log.Errorf("Could not parse global ui settings: %v\n", err)
|
||||||
}
|
}
|
||||||
|
log.Debugf("MAP: %v", settings.Experiments)
|
||||||
return &settings
|
return &settings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
main.go
4
main.go
|
@ -4,10 +4,11 @@ import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
libapp "cwtch.im/cwtch/app"
|
libapp "cwtch.im/cwtch/app"
|
||||||
"cwtch.im/cwtch/event"
|
"cwtch.im/cwtch/event"
|
||||||
"cwtch.im/cwtch/peer"
|
|
||||||
"cwtch.im/cwtch/event/bridge"
|
"cwtch.im/cwtch/event/bridge"
|
||||||
|
"cwtch.im/cwtch/peer"
|
||||||
"cwtch.im/ui/go/handlers"
|
"cwtch.im/ui/go/handlers"
|
||||||
os2 "cwtch.im/ui/go/os"
|
os2 "cwtch.im/ui/go/os"
|
||||||
|
"cwtch.im/ui/go/servers"
|
||||||
"cwtch.im/ui/go/the"
|
"cwtch.im/ui/go/the"
|
||||||
"cwtch.im/ui/go/ui"
|
"cwtch.im/ui/go/ui"
|
||||||
"cwtch.im/ui/go/ui/android"
|
"cwtch.im/ui/go/ui/android"
|
||||||
|
@ -319,6 +320,7 @@ func loadNetworkingAndFiles(gcd *ui.GrandCentralDispatcher, service bool, client
|
||||||
the.AppBus = the.CwtchApp.GetPrimaryBus()
|
the.AppBus = the.CwtchApp.GetPrimaryBus()
|
||||||
subscribed := make(chan bool)
|
subscribed := make(chan bool)
|
||||||
go handlers.App(gcd, subscribed, clientUI)
|
go handlers.App(gcd, subscribed, clientUI)
|
||||||
|
go servers.LaunchServiceManager(gcd)
|
||||||
<-subscribed
|
<-subscribed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
qml/main.qml
12
qml/main.qml
|
@ -111,6 +111,7 @@ ApplicationWindow {
|
||||||
readonly property int settingsPane: 2
|
readonly property int settingsPane: 2
|
||||||
readonly property int addEditProfilePane: 3
|
readonly property int addEditProfilePane: 3
|
||||||
readonly property int profilePane: 4
|
readonly property int profilePane: 4
|
||||||
|
readonly property int addEditServerPane: 5
|
||||||
property alias pane: parentStack.currentIndex
|
property alias pane: parentStack.currentIndex
|
||||||
|
|
||||||
Rectangle { // Splash pane
|
Rectangle { // Splash pane
|
||||||
|
@ -164,7 +165,6 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RowLayout { // Profile Pane (contact list + overlays)
|
RowLayout { // Profile Pane (contact list + overlays)
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
@ -251,8 +251,18 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle { // Server Add / Edit pane
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: Theme.backgroundPaneColor
|
||||||
|
|
||||||
|
|
||||||
|
ServerAddEditPane{
|
||||||
|
id: serverAddEditPane
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
focus: true
|
focus: true
|
||||||
Keys.onPressed: {
|
Keys.onPressed: {
|
||||||
if (event.key == Qt.Key_Back) {
|
if (event.key == Qt.Key_Back) {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import "../opaque/styles"
|
||||||
import "../opaque/theme"
|
import "../opaque/theme"
|
||||||
import "../opaque/fonts"
|
import "../opaque/fonts"
|
||||||
|
|
||||||
|
import "../utils.js" as Utils
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: thecol
|
id: thecol
|
||||||
|
@ -127,6 +128,8 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
// TODO Remove Experiment Check once Feature is Stable
|
||||||
|
visible: gcd.experimentsEnabled && Utils.checkMap(gcd.experiments, "tapir-servers-experiment")
|
||||||
color: Theme.backgroundMainColor
|
color: Theme.backgroundMainColor
|
||||||
|
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Controls 2.13
|
||||||
|
import QtQuick.Controls.Material 2.0
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import QtQuick.Window 2.11
|
||||||
|
|
||||||
|
|
||||||
|
import "../opaque" as Opaque
|
||||||
|
import "../opaque/theme"
|
||||||
|
// import "../styles"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Opaque.SettingsList { // Add Profile Pane
|
||||||
|
id: serverAddEditPane
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
serverAddEditPane.server_name = "";
|
||||||
|
serverAddEditPane.server_available = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
property string server_name;
|
||||||
|
property bool server_available;
|
||||||
|
|
||||||
|
function load(server_onion, server_name, server_available) {
|
||||||
|
reset();
|
||||||
|
serverAddEditPane.server_name = server_name;
|
||||||
|
serverAddEditPane.server_available = server_available;
|
||||||
|
}
|
||||||
|
|
||||||
|
settings: Column {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: 700
|
||||||
|
|
||||||
|
Opaque.ScalingLabel {
|
||||||
|
text: server_name
|
||||||
|
size: 48
|
||||||
|
}
|
||||||
|
|
||||||
|
Opaque.Setting {
|
||||||
|
label: qsTr("server-availability")
|
||||||
|
|
||||||
|
|
||||||
|
field: Opaque.ToggleSwitch {
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
isToggled: serverAddEditPane.server_available
|
||||||
|
onToggled: function() {
|
||||||
|
serverAddEditPane.serverAddEditPane = !serverAddEditPane
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Connections { // UPDATE UNREAD MESSAGES COUNTER
|
||||||
|
target: gcd
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,8 @@ import QtQuick.Controls.Styles 1.4
|
||||||
import "../opaque" as Opaque
|
import "../opaque" as Opaque
|
||||||
import "../opaque/controls"
|
import "../opaque/controls"
|
||||||
import "../opaque/theme"
|
import "../opaque/theme"
|
||||||
|
import "../widgets" as Widgets
|
||||||
|
import "../utils.js" as Utils
|
||||||
|
|
||||||
Opaque.SettingsList { // settingsPane
|
Opaque.SettingsList { // settingsPane
|
||||||
id: root
|
id: root
|
||||||
|
@ -118,6 +120,37 @@ Opaque.SettingsList { // settingsPane
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Experimental Gating
|
||||||
|
|
||||||
|
Opaque.Setting {
|
||||||
|
//: Theme
|
||||||
|
label: qsTr("experiments-enabled")
|
||||||
|
|
||||||
|
field: Opaque.ToggleSwitch {
|
||||||
|
anchors.right: parent.right
|
||||||
|
id: experimentsEnabledToggle
|
||||||
|
isToggled: gcd.experimentsEnabled
|
||||||
|
onToggled: function() {
|
||||||
|
console.log("experiments enabled: " + gcd.experimentsEnabled + " " + experimentsEnabledToggle.isToggled) ;
|
||||||
|
if (gcd.experimentsEnabled == false) {
|
||||||
|
gcd.experimentsEnabled = true;
|
||||||
|
} else {
|
||||||
|
gcd.experimentsEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widgets.ExperimentToggle {
|
||||||
|
name: "servers_enabled"
|
||||||
|
experiment_id: "tapir-servers-experiment"
|
||||||
|
}
|
||||||
|
|
||||||
|
Widgets.ExperimentToggle {
|
||||||
|
name: "groups_enabled"
|
||||||
|
experiment_id: "tapir-groups-experiment"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,33 +201,3 @@ Opaque.SettingsList { // settingsPane
|
||||||
//end of flickable
|
//end of flickable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Opaque.ScalingLabel {
|
|
||||||
width: parent.width
|
|
||||||
wrapMode: TextEdit.Wrap
|
|
||||||
//: Interface zoom (mostly affects text and button sizes)
|
|
||||||
text: qsTr("zoom-label") + ":"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CheckBox {
|
|
||||||
id: blockUnknownToggle
|
|
||||||
checked: true
|
|
||||||
onClicked: {
|
|
||||||
if (blockUnknownToggle.checked) {
|
|
||||||
gcd.blockUnknownPeers()
|
|
||||||
} else {
|
|
||||||
gcd.allowUnknownPeers()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
style: CheckBoxStyle {
|
|
||||||
label: Opaque.ScalingLabel {
|
|
||||||
text: qsTr("block-unknown-label")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
16
qml/utils.js
16
qml/utils.js
|
@ -46,6 +46,22 @@ function isGridOccupied(x, y, points) {
|
||||||
return inPoints
|
return inPoints
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkMap(obj, key) {
|
||||||
|
let map = buildMap(obj);
|
||||||
|
if (map[key] != undefined) {
|
||||||
|
return map[key];
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildMap(obj) {
|
||||||
|
let map = new Map();
|
||||||
|
Object.keys(obj).forEach(key => {
|
||||||
|
map[key] = obj[key];
|
||||||
|
});
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
function isGroup(id) {
|
function isGroup(id) {
|
||||||
return id.length == 32
|
return id.length == 32
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import "../opaque" as Opaque
|
||||||
|
import "../opaque/controls"
|
||||||
|
import "../opaque/theme"
|
||||||
|
import "../utils.js" as Utils
|
||||||
|
|
||||||
|
Opaque.Setting {
|
||||||
|
//: Theme
|
||||||
|
id: experiment
|
||||||
|
property string name;
|
||||||
|
property string experiment_id;
|
||||||
|
visible: gcd.experimentsEnabled
|
||||||
|
label: qsTr(name)
|
||||||
|
|
||||||
|
field: Opaque.ToggleSwitch {
|
||||||
|
anchors.right: parent.right
|
||||||
|
id: expToggle
|
||||||
|
isToggled: Utils.checkMap(gcd.experiments, experiment.experiment_id)
|
||||||
|
onToggled: function() {
|
||||||
|
let experimentsMap = Utils.buildMap(gcd.experiments);
|
||||||
|
experimentsMap[experiment.experiment_id] = expToggle.isToggled ? false : true;
|
||||||
|
gcd.experiments = experimentsMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,62 +36,54 @@ ColumnLayout {
|
||||||
Connections { // ADD/REMOVE CONTACT ENTRIES
|
Connections { // ADD/REMOVE CONTACT ENTRIES
|
||||||
target: gcd
|
target: gcd
|
||||||
|
|
||||||
onAddProfile: function(handle, displayName, image, tag) {
|
onLoaded: function() {
|
||||||
|
gcd.requestServers();
|
||||||
|
}
|
||||||
|
|
||||||
|
onAddServer: function(handle, displayName, image, status) {
|
||||||
|
|
||||||
// don't add duplicates
|
// don't add duplicates
|
||||||
for (var i = 0; i < profilesModel.count; i++) {
|
for (var i = 0; i < serversModel.count; i++) {
|
||||||
if (profilesModel.get(i)["_handle"] == handle) {
|
if (serversModel.get(i)["_handle"] == handle) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// find index for insert (sort by onion)
|
// find index for insert (sort by onion)
|
||||||
var index = profilesModel.count
|
var index = serversModel.count
|
||||||
for (var i = 0; i < profilesModel.count; i++) {
|
for (var i = 0; i < serversModel.count; i++) {
|
||||||
if (profilesModel.get(i)["_handle"] > handle) {
|
if (serversModel.get(i)["_handle"] > handle) {
|
||||||
index = i
|
index = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profilesModel.insert(index,
|
serversModel.insert(index,
|
||||||
{
|
{
|
||||||
_handle: handle,
|
_handle: handle,
|
||||||
_displayName: displayName,
|
_displayName: displayName,
|
||||||
_image: image,
|
_image: image,
|
||||||
_tag: tag,
|
_status: status,
|
||||||
_status: 4,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
onResetServerList: function() {
|
||||||
onRemoveProfile: function(handle) {
|
serversModel.clear()
|
||||||
for(var i = 0; i < profilesModel.count; i++){
|
|
||||||
if(profilesModel.get(i)["_handle"] == handle) {
|
|
||||||
console.log("deleting contact " + profilesModel.get(i)["_handle"])
|
|
||||||
profilesModel.remove(i)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
onResetProfileList: function() {
|
|
||||||
profilesModel.clear()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ListModel { // Profile OBJECTS ARE STORED HERE ...
|
ListModel { // Profile OBJECTS ARE STORED HERE ...
|
||||||
id: profilesModel
|
id: serversModel
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: profileList
|
id: serverList
|
||||||
model: profilesModel // ... AND DISPLAYED HERE
|
model: serversModel // ... AND DISPLAYED HERE
|
||||||
delegate: ProfileRow {
|
delegate: ServerRow {
|
||||||
handle: _handle
|
handle: _handle
|
||||||
displayName: _displayName
|
displayName: _displayName
|
||||||
image: _image
|
image: _image
|
||||||
tag: _tag
|
status: _status
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,8 +105,11 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
badgeColor: Theme.defaultButtonColor
|
badgeColor: Theme.defaultButtonColor
|
||||||
|
|
||||||
onClicked: function(handle) { profileAddEditPane.reset(); parentStack.pane = parentStack.addEditProfilePane }
|
onClicked: function(handle) { serverAddEditPane.reset(); parentStack.pane = parentStack.addEditServerPane }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
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 CustomQmlTypes 1.0
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import QtQuick.Controls.Styles 1.4
|
||||||
|
|
||||||
|
import "../opaque" as Opaque
|
||||||
|
import "../opaque/styles"
|
||||||
|
import "../opaque/theme"
|
||||||
|
|
||||||
|
Opaque.PortraitRow {
|
||||||
|
id: root
|
||||||
|
property int status;
|
||||||
|
|
||||||
|
portraitBorderColor: Theme.portraitOnlineBorderColor
|
||||||
|
portraitColor: Theme.portraitOnlineBackgroundColor
|
||||||
|
nameColor: Theme.portraitOnlineTextColor
|
||||||
|
onionColor: Theme.portraitOnlineTextColor
|
||||||
|
|
||||||
|
badgeColor: status == 4 ? Theme.portraitOnlineBadgeColor : Theme.portraitOfflineBadgeColor
|
||||||
|
badgeVisible: true
|
||||||
|
|
||||||
|
Opaque.Icon {// Edit BUTTON
|
||||||
|
id: btnEdit
|
||||||
|
source: gcd.assetPath + "core/edit-24px.svg"
|
||||||
|
|
||||||
|
backgroundColor: root.color
|
||||||
|
iconColor: Theme.altTextColor
|
||||||
|
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
//rectUnread.left
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.leftMargin: 1 * gcd.themeScale
|
||||||
|
anchors.rightMargin: 20 * gcd.themeScale
|
||||||
|
|
||||||
|
height: parent.height * 0.5
|
||||||
|
width: parent.height * 0.5
|
||||||
|
size: parent.height * 0.5
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
serverAddEditPane.load(handle, displayName, status)
|
||||||
|
parentStack.pane = parentStack.addEditServerPane
|
||||||
|
}
|
||||||
|
|
||||||
|
onHover: function (hover) {
|
||||||
|
root.isHover = hover
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: function openClick(handle) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Reference in New Issue