Formatting
the build was successful Details

This commit is contained in:
Sarah Jamie Lewis 2020-11-23 13:13:09 -08:00
parent 228a9b6ebd
commit e74a0e8dc2
9 changed files with 83 additions and 96 deletions

View File

@ -4,23 +4,23 @@ import "cwtch.im/cwtch/event"
// The server manager defines its own events, most should be self-explanatory: // The server manager defines its own events, most should be self-explanatory:
const ( const (
NewServer = event.Type("NewServer") NewServer = event.Type("NewServer")
// Force a UI update // Force a UI update
ListServers = event.Type("ListServers") ListServers = event.Type("ListServers")
// Takes an Onion, used to toggle off/on Server availability // Takes an Onion, used to toggle off/on Server availability
StartServer = event.Type("StartServer") StartServer = event.Type("StartServer")
StopServer = event.Type("StopServer") StopServer = event.Type("StopServer")
// Takes an Onion and a AutoStartEnabled boolean // Takes an Onion and a AutoStartEnabled boolean
AutoStart = event.Type("AutoStart") AutoStart = event.Type("AutoStart")
// Get the status of a particular server (takes an Onion) // Get the status of a particular server (takes an Onion)
CheckServerStatus = event.Type("CheckServerStatus") CheckServerStatus = event.Type("CheckServerStatus")
ServerStatusUpdate = event.Type("ServerStatusUpdate") ServerStatusUpdate = event.Type("ServerStatusUpdate")
) )
const ( const (
AutoStartEnabled = event.Field("AutoStartEnabled") AutoStartEnabled = event.Field("AutoStartEnabled")
) )

View File

@ -14,13 +14,11 @@ const TofuBundlePrefix = "tofubundle:"
const GroupPrefix = "torv3" const GroupPrefix = "torv3"
const GroupExperiment = "tapir-groups-experiment" const GroupExperiment = "tapir-groups-experiment"
type GroupFunctionality struct { type GroupFunctionality struct {
} }
// ExperimentGate returns GroupFunctionality if the experiment is enabled, and an error otherwise. // ExperimentGate returns GroupFunctionality if the experiment is enabled, and an error otherwise.
func ExperimentGate(experimentMap map[string]bool) (*GroupFunctionality,error) { func ExperimentGate(experimentMap map[string]bool) (*GroupFunctionality, error) {
if experimentMap[GroupExperiment] { if experimentMap[GroupExperiment] {
return new(GroupFunctionality), nil return new(GroupFunctionality), nil
} }
@ -49,10 +47,10 @@ func (gf *GroupFunctionality) ValidPrefix(importString string) bool {
} }
// HandleImportString handles import strings for groups and servers // HandleImportString handles import strings for groups and servers
func (gf * GroupFunctionality) HandleImportString(importString string) error { func (gf *GroupFunctionality) HandleImportString(importString string) error {
if strings.HasPrefix(importString, TofuBundlePrefix) { if strings.HasPrefix(importString, TofuBundlePrefix) {
bundle := strings.Split(importString,"||") bundle := strings.Split(importString, "||")
gf.HandleImportString(bundle[0][11:]) gf.HandleImportString(bundle[0][11:])
gf.HandleImportString(bundle[1]) gf.HandleImportString(bundle[1])
return nil return nil
@ -68,10 +66,9 @@ func (gf * GroupFunctionality) HandleImportString(importString string) error {
} }
//eg: torv3JFDWkXExBsZLkjvfkkuAxHsiLGZBk0bvoeJID9ItYnU=EsEBCiBhOWJhZDU1OTQ0NWI3YmM2N2YxYTM5YjkzMTNmNTczNRIgpHeNaG+6jy750eDhwLO39UX4f2xs0irK/M3P6mDSYQIaOTJjM2ttb29ibnlnaGoyenc2cHd2N2Q1N3l6bGQ3NTNhdW8zdWdhdWV6enB2ZmFrM2FoYzRiZHlkCiJAdVSSVgsksceIfHe41OJu9ZFHO8Kwv3G6F5OK3Hw4qZ6hn6SiZjtmJlJezoBH0voZlCahOU7jCOg+dsENndZxAA== //eg: torv3JFDWkXExBsZLkjvfkkuAxHsiLGZBk0bvoeJID9ItYnU=EsEBCiBhOWJhZDU1OTQ0NWI3YmM2N2YxYTM5YjkzMTNmNTczNRIgpHeNaG+6jy750eDhwLO39UX4f2xs0irK/M3P6mDSYQIaOTJjM2ttb29ibnlnaGoyenc2cHd2N2Q1N3l6bGQ3NTNhdW8zdWdhdWV6enB2ZmFrM2FoYzRiZHlkCiJAdVSSVgsksceIfHe41OJu9ZFHO8Kwv3G6F5OK3Hw4qZ6hn6SiZjtmJlJezoBH0voZlCahOU7jCOg+dsENndZxAA==
if strings.HasPrefix(importString, GroupPrefix){ if strings.HasPrefix(importString, GroupPrefix) {
return the.Peer.ImportGroup(importString) return the.Peer.ImportGroup(importString)
} }
return errors.New("invalid_group_invite_prefix") return errors.New("invalid_group_invite_prefix")
} }

View File

@ -2,9 +2,8 @@ package groups
import "testing" import "testing"
func TestGroupFunctionality_ValidPrefix(t *testing.T) { func TestGroupFunctionality_ValidPrefix(t *testing.T) {
gf,_ := ExperimentGate(map[string]bool{GroupExperiment: true}) gf, _ := ExperimentGate(map[string]bool{GroupExperiment: true})
if gf.ValidPrefix("torv3blahblahblah") == false { if gf.ValidPrefix("torv3blahblahblah") == false {
t.Fatalf("torv3 should be a valid prefix") t.Fatalf("torv3 should be a valid prefix")
} }
@ -21,20 +20,20 @@ func TestGroupFunctionality_ValidPrefix(t *testing.T) {
func TestGroupFunctionality_IsEnabled(t *testing.T) { func TestGroupFunctionality_IsEnabled(t *testing.T) {
_,err := ExperimentGate(map[string]bool{}) _, err := ExperimentGate(map[string]bool{})
if err == nil { if err == nil {
t.Fatalf("group functionality should be disabled") t.Fatalf("group functionality should be disabled")
} }
_,err = ExperimentGate(map[string]bool{GroupExperiment: true}) _, err = ExperimentGate(map[string]bool{GroupExperiment: true})
if err != nil { if err != nil {
t.Fatalf("group functionality should be enabled") t.Fatalf("group functionality should be enabled")
} }
_,err = ExperimentGate(map[string]bool{GroupExperiment: false}) _, err = ExperimentGate(map[string]bool{GroupExperiment: false})
if err == nil { if err == nil {
t.Fatalf("group functionality should be disabled") t.Fatalf("group functionality should be disabled")
} }
} }

View File

@ -21,23 +21,20 @@ import (
"sync" "sync"
) )
// ServerManager is responsible for managing user operated servers // ServerManager is responsible for managing user operated servers
type ServerManager struct { type ServerManager struct {
servers sync.Map servers sync.Map
configDir string configDir string
acn connectivity.ACN acn connectivity.ACN
} }
type serverStatusCache struct { type serverStatusCache struct {
online bool online bool
autostart bool autostart bool
messages uint64 messages uint64
bundle []byte bundle []byte
} }
// LaunchServiceManager is responsible for setting up everything relating to managing servers in the UI. // LaunchServiceManager is responsible for setting up everything relating to managing servers in the UI.
func LaunchServiceManager(gcd *ui.GrandCentralDispatcher, acn connectivity.ACN, configDir string) { func LaunchServiceManager(gcd *ui.GrandCentralDispatcher, acn connectivity.ACN, configDir string) {
sm := new(ServerManager) sm := new(ServerManager)
@ -48,7 +45,7 @@ func LaunchServiceManager(gcd *ui.GrandCentralDispatcher, acn connectivity.ACN,
// initializeServerCache sets up a new cache based on the config. Notably it stores a newly signed keybundle that // initializeServerCache sets up a new cache based on the config. Notably it stores a newly signed keybundle that
// the ui uses to allow people to share server key bundles. // the ui uses to allow people to share server key bundles.
func initializeServerCache(config server.Config) (*server.Server,serverStatusCache) { func initializeServerCache(config server.Config) (*server.Server, serverStatusCache) {
newServer := new(server.Server) newServer := new(server.Server)
newServer.Setup(config) newServer.Setup(config)
newServer.KeyBundle() newServer.KeyBundle()
@ -75,7 +72,7 @@ func (sm *ServerManager) Init(gcd *ui.GrandCentralDispatcher) {
// many of risks e.g lack of server diversification / availability of servers. // many of risks e.g lack of server diversification / availability of servers.
// Like many parts of the metadata resistant risk model, it is a compromise // Like many parts of the metadata resistant risk model, it is a compromise
log.Debugf("Reading server directory: %v", sm.configDir) log.Debugf("Reading server directory: %v", sm.configDir)
os.MkdirAll(sm.configDir,0700) os.MkdirAll(sm.configDir, 0700)
items, _ := ioutil.ReadDir(sm.configDir) items, _ := ioutil.ReadDir(sm.configDir)
for _, item := range items { for _, item := range items {
if item.IsDir() { if item.IsDir() {
@ -83,7 +80,7 @@ func (sm *ServerManager) Init(gcd *ui.GrandCentralDispatcher) {
config := server.LoadConfig(path.Join(sm.configDir, item.Name()), "serverconfig") config := server.LoadConfig(path.Join(sm.configDir, item.Name()), "serverconfig")
identity := config.Identity() identity := config.Identity()
log.Debugf("Launching Server goroutine for %v", identity.Hostname()) log.Debugf("Launching Server goroutine for %v", identity.Hostname())
s,cache := initializeServerCache(config) s, cache := initializeServerCache(config)
sm.servers.Store(identity.Hostname(), cache) sm.servers.Store(identity.Hostname(), cache)
go sm.runServer(s) go sm.runServer(s)
} else { } else {
@ -112,24 +109,23 @@ func (sm *ServerManager) Init(gcd *ui.GrandCentralDispatcher) {
} }
} }
// NewServer createa a new server // NewServer createa a new server
func (sm *ServerManager) NewServer() { func (sm *ServerManager) NewServer() {
log.Debugf("Adding a new Server") log.Debugf("Adding a new Server")
num, err := rand.Int(rand.Reader, big.NewInt(math.MaxUint32)) num, err := rand.Int(rand.Reader, big.NewInt(math.MaxUint32))
if err == nil { if err == nil {
serverDir := path.Join(sm.configDir, num.String()); serverDir := path.Join(sm.configDir, num.String())
os.MkdirAll(serverDir,0700) os.MkdirAll(serverDir, 0700)
config := server.LoadConfig(serverDir, "serverconfig") config := server.LoadConfig(serverDir, "serverconfig")
identity := config.Identity() identity := config.Identity()
s, cache := initializeServerCache(config) s, cache := initializeServerCache(config)
sm.servers.Store(identity.Hostname(),cache) sm.servers.Store(identity.Hostname(), cache)
go sm.runServer(s) go sm.runServer(s)
} }
} }
// runServer sets up an event queue per server to allow them to manage their own state. // runServer sets up an event queue per server to allow them to manage their own state.
func (sm *ServerManager) runServer(s * server.Server) { func (sm *ServerManager) runServer(s *server.Server) {
q := event.NewQueue() q := event.NewQueue()
the.AppBus.Subscribe(constants.StartServer, q) the.AppBus.Subscribe(constants.StartServer, q)
the.AppBus.Subscribe(constants.StopServer, q) the.AppBus.Subscribe(constants.StopServer, q)
@ -137,10 +133,9 @@ func (sm *ServerManager) runServer(s * server.Server) {
the.AppBus.Subscribe(constants.AutoStart, q) the.AppBus.Subscribe(constants.AutoStart, q)
the.AppBus.Subscribe(event.Shutdown, q) the.AppBus.Subscribe(event.Shutdown, q)
identity := s.Identity() identity := s.Identity()
cache,ok := sm.servers.Load(identity.Hostname()) cache, ok := sm.servers.Load(identity.Hostname())
if ok { if ok {
serverStatusCache := cache.(serverStatusCache) serverStatusCache := cache.(serverStatusCache)
if serverStatusCache.autostart { if serverStatusCache.autostart {
@ -148,7 +143,6 @@ func (sm *ServerManager) runServer(s * server.Server) {
} }
} }
log.Debugf("Launching Server %v", identity.Hostname()) log.Debugf("Launching Server %v", identity.Hostname())
log.Debugf("Launching Event Bus for Server %v", identity.Hostname()) log.Debugf("Launching Event Bus for Server %v", identity.Hostname())
for { for {
@ -158,7 +152,7 @@ func (sm *ServerManager) runServer(s * server.Server) {
case constants.StartServer: case constants.StartServer:
onion := e.Data[event.Onion] onion := e.Data[event.Onion]
if onion == identity.Hostname() { if onion == identity.Hostname() {
if running,_ := s.CheckStatus(); running { if running, _ := s.CheckStatus(); running {
// we are already running // we are already running
log.Debugf("Server %v Already Running", onion) log.Debugf("Server %v Already Running", onion)
continue continue
@ -175,7 +169,7 @@ func (sm *ServerManager) runServer(s * server.Server) {
panic(err) panic(err)
} }
fmt.Printf("Secret Debugging Group for Testing: %v\n", "torv3"+base64.StdEncoding.EncodeToString(invite)) fmt.Printf("Secret Debugging Group for Testing: %v\n", "torv3"+base64.StdEncoding.EncodeToString(invite))
cache,ok := sm.servers.Load(onion) cache, ok := sm.servers.Load(onion)
if ok { if ok {
serverStatusCache := cache.(serverStatusCache) serverStatusCache := cache.(serverStatusCache)
serverStatusCache.online = true serverStatusCache.online = true
@ -187,7 +181,7 @@ func (sm *ServerManager) runServer(s * server.Server) {
onion := e.Data[event.Onion] onion := e.Data[event.Onion]
if onion == identity.Hostname() { if onion == identity.Hostname() {
s.Shutdown() s.Shutdown()
cache,ok := sm.servers.Load(onion) cache, ok := sm.servers.Load(onion)
if ok { if ok {
serverStatusCache := cache.(serverStatusCache) serverStatusCache := cache.(serverStatusCache)
serverStatusCache.online = false serverStatusCache.online = false
@ -217,7 +211,7 @@ func (sm *ServerManager) runServer(s * server.Server) {
if onion == identity.Hostname() { if onion == identity.Hostname() {
autostart := e.Data[constants.AutoStartEnabled] == event.True autostart := e.Data[constants.AutoStartEnabled] == event.True
s.ConfigureAutostart(autostart) s.ConfigureAutostart(autostart)
cache,ok := sm.servers.Load(onion) cache, ok := sm.servers.Load(onion)
if ok { if ok {
serverStatusCache := cache.(serverStatusCache) serverStatusCache := cache.(serverStatusCache)
serverStatusCache.autostart = autostart serverStatusCache.autostart = autostart
@ -226,8 +220,8 @@ func (sm *ServerManager) runServer(s * server.Server) {
} }
} }
case event.Shutdown: case event.Shutdown:
s.Shutdown() s.Shutdown()
return return
} }
} }
} }
@ -236,7 +230,7 @@ func (sm *ServerManager) runServer(s * server.Server) {
// cache and sends an update to the UI. // cache and sends an update to the UI.
func (sm *ServerManager) ListServers(gcd *ui.GrandCentralDispatcher) { func (sm *ServerManager) ListServers(gcd *ui.GrandCentralDispatcher) {
log.Debugf("Listing Servers...") log.Debugf("Listing Servers...")
sm.servers.Range(func(k interface{},v interface{}) bool { sm.servers.Range(func(k interface{}, v interface{}) bool {
serverOnion := k.(string) serverOnion := k.(string)
statusCache := v.(serverStatusCache) statusCache := v.(serverStatusCache)
status := 0 status := 0
@ -249,19 +243,19 @@ func (sm *ServerManager) ListServers(gcd *ui.GrandCentralDispatcher) {
var keyNames []string var keyNames []string
var keys []string var keys []string
keybundle,_ := model.DeserializeAndVerify(statusCache.bundle) keybundle, _ := model.DeserializeAndVerify(statusCache.bundle)
for _, key_type := range key_types { for _, key_type := range key_types {
log.Debugf("Looking up %v %v", key_type, keyNames) log.Debugf("Looking up %v %v", key_type, keyNames)
if keybundle.HasKeyType(key_type) { if keybundle.HasKeyType(key_type) {
key,_ := keybundle.GetKey(key_type) key, _ := keybundle.GetKey(key_type)
keyNames = append(keyNames, string(key_type)) keyNames = append(keyNames, string(key_type))
keys = append(keys, string(key)) keys = append(keys, string(key))
} }
} }
log.Debugf("Updating Server %v %v %v", serverOnion, status, statusCache.messages) log.Debugf("Updating Server %v %v %v", serverOnion, status, statusCache.messages)
gcd.AddServer(serverOnion,serverOnion,serverOnion, status, statusCache.autostart, "server:"+base64.StdEncoding.EncodeToString(statusCache.bundle), int(statusCache.messages), keyNames, keys) gcd.AddServer(serverOnion, serverOnion, serverOnion, status, statusCache.autostart, "server:"+base64.StdEncoding.EncodeToString(statusCache.bundle), int(statusCache.messages), keyNames, keys)
return true return true
}) })
} }

View File

@ -14,11 +14,11 @@ import (
// On unix systems the command "ps" is practically universal and should suffice for this... // On unix systems the command "ps" is practically universal and should suffice for this...
func CheckProcessAndKill(pid uint64, processName string) { func CheckProcessAndKill(pid uint64, processName string) {
log.Debugf("killing: %v", pid) log.Debugf("killing: %v", pid)
bytes,err := exec.Command("ps", "-p", strconv.Itoa(int(pid)), "-o", "command").Output() bytes, err := exec.Command("ps", "-p", strconv.Itoa(int(pid)), "-o", "command").Output()
if err == nil { if err == nil {
// check for a binary @ "/<process_name>" // check for a binary @ "/<process_name>"
lines := strings.Split(string(bytes), "\n") lines := strings.Split(string(bytes), "\n")
if len(lines) >= 2 && strings.Contains(lines[1],"/"+processName+" ") { if len(lines) >= 2 && strings.Contains(lines[1], "/"+processName+" ") {
Kill(pid) Kill(pid)
return return
} }
@ -32,7 +32,7 @@ func CheckProcessAndKill(pid uint64, processName string) {
// Kill a process based on pid // Kill a process based on pid
func Kill(pid uint64) { func Kill(pid uint64) {
log.Debugf("killing: %v", pid) log.Debugf("killing: %v", pid)
bytes,err := exec.Command("kill", strconv.Itoa(int(pid))).Output() bytes, err := exec.Command("kill", strconv.Itoa(int(pid))).Output()
if err == nil { if err == nil {
log.Debugf("kill %v successful: %s", pid, bytes) log.Debugf("kill %v successful: %s", pid, bytes)
} else { } else {
@ -40,4 +40,4 @@ func Kill(pid uint64) {
log.Debugf("could not kill pid: %v %v", pid, err) log.Debugf("could not kill pid: %v %v", pid, err)
} }
return return
} }

View File

@ -13,18 +13,18 @@ import (
// On windows this uses tasklist... // On windows this uses tasklist...
func CheckProcessAndKill(pid uint64, processName string) { func CheckProcessAndKill(pid uint64, processName string) {
log.Debugf("looking up process: %v", pid) log.Debugf("looking up process: %v", pid)
bytes,err := exec.Command("tasklist", "/fi", "pid eq "+strconv.Itoa(int(pid))).Output() bytes, err := exec.Command("tasklist", "/fi", "pid eq "+strconv.Itoa(int(pid))).Output()
if err == nil { if err == nil {
// Output will be something like this: // Output will be something like this:
// //
// Image Name PID Session Name Session# Mem Usage // Image Name PID Session Name Session# Mem Usage
// ========================= ======== ================ =========== ============ // ========================= ======== ================ =========== ============
// process.exe <PID> Services 0 8,936 K // process.exe <PID> Services 0 8,936 K
lines := strings.Split(strings.TrimSpace(string(bytes)),"\n") lines := strings.Split(strings.TrimSpace(string(bytes)), "\n")
log.Debugf("%v\n", lines) log.Debugf("%v\n", lines)
// check for "<process>.exe" // check for "<process>.exe"
if len(lines) >= 3 && strings.HasPrefix(strings.ToLower(strings.TrimSpace(lines[2])),processName+".exe") { if len(lines) >= 3 && strings.HasPrefix(strings.ToLower(strings.TrimSpace(lines[2])), processName+".exe") {
Kill(pid) Kill(pid)
return return
} }
@ -37,7 +37,7 @@ func CheckProcessAndKill(pid uint64, processName string) {
// Kill a process based on pid // Kill a process based on pid
func Kill(pid uint64) { func Kill(pid uint64) {
log.Debugf("killing: %v", pid) log.Debugf("killing: %v", pid)
bytes,err := exec.Command("taskkill", "/F", "/PID", strconv.Itoa(int(pid))).Output() bytes, err := exec.Command("taskkill", "/F", "/PID", strconv.Itoa(int(pid))).Output()
if err == nil { if err == nil {
log.Debugf("kill %v successful: %s", pid, bytes) log.Debugf("kill %v successful: %s", pid, bytes)
} else { } else {
@ -45,4 +45,4 @@ func Kill(pid uint64) {
log.Debugf("could not kill pid: %v %v", pid, err) log.Debugf("could not kill pid: %v %v", pid, err)
} }
return return
} }

View File

@ -36,10 +36,9 @@ type GrandCentralDispatcher struct {
m_selectedProfile string m_selectedProfile string
m_selectedConversation string m_selectedConversation string
_ int `property:"torStatus"`
_ int `property:"torStatus"`
_ string `property:"os"` _ string `property:"os"`
_ bool `property:"firstTime"` _ bool `property:"firstTime"`
_ float32 `property:"themeScale,auto,changed"` _ float32 `property:"themeScale,auto,changed"`
_ string `property:"theme,auto,changed"` _ string `property:"theme,auto,changed"`
_ string `property:"locale,auto,changed"` _ string `property:"locale,auto,changed"`
@ -142,7 +141,7 @@ type GrandCentralDispatcher struct {
func (this *GrandCentralDispatcher) init() { func (this *GrandCentralDispatcher) init() {
this.uIManagers = make(map[string]Manager) this.uIManagers = make(map[string]Manager)
firstTime := false firstTime := false
this.GlobalSettings,firstTime = ReadGlobalSettings() this.GlobalSettings, firstTime = ReadGlobalSettings()
this.SetFirstTime(firstTime) this.SetFirstTime(firstTime)
this.SetThemeScale(this.GlobalSettings.Zoom) this.SetThemeScale(this.GlobalSettings.Zoom)
this.SetTheme(this.GlobalSettings.Theme) this.SetTheme(this.GlobalSettings.Theme)

View File

@ -15,7 +15,7 @@ type MessageModel struct {
ackIdx int ackIdx int
handle string handle string
_ func(string) `signal:"setHandle,auto"` _ func(string) `signal:"setHandle,auto"`
_ map[int]*core.QByteArray `property:"roles"` _ map[int]*core.QByteArray `property:"roles"`
_ func() `constructor:"init"` _ func() `constructor:"init"`
@ -32,17 +32,17 @@ type MessageWrapper struct {
model.Message model.Message
core.QObject core.QObject
Timestamp int64 Timestamp int64
PeerID string PeerID string
Acknowledged bool Acknowledged bool
RawMessage string RawMessage string
Error string Error string
Day string Day string
Signature string Signature string
_ bool `property:"ackd"` _ bool `property:"ackd"`
} }
func (this *MessageModel) Handle() string{ func (this *MessageModel) Handle() string {
return this.handle return this.handle
} }
@ -50,7 +50,6 @@ func (this *MessageModel) setHandle(handle string) {
this.handle = handle this.handle = handle
} }
func (this *MessageModel) init() { func (this *MessageModel) init() {
mdt := reflect.TypeOf([]MessageWrapper{}).Elem() mdt := reflect.TypeOf([]MessageWrapper{}).Elem()
roles := make(map[int]*core.QByteArray) roles := make(map[int]*core.QByteArray)
@ -58,7 +57,7 @@ func (this *MessageModel) init() {
if mdt.Field(i).Name == "Acknowledged" { if mdt.Field(i).Name == "Acknowledged" {
this.ackIdx = int(core.Qt__UserRole) + 1 + i this.ackIdx = int(core.Qt__UserRole) + 1 + i
} }
roles[int(core.Qt__UserRole) + 1 + i] = core.NewQByteArray2(mdt.Field(i).Name, -1) roles[int(core.Qt__UserRole)+1+i] = core.NewQByteArray2(mdt.Field(i).Name, -1)
} }
roles[int(core.Qt__DisplayRole)] = core.NewQByteArray2("display", -1) roles[int(core.Qt__DisplayRole)] = core.NewQByteArray2("display", -1)
this.SetRoles(roles) this.SetRoles(roles)
@ -109,13 +108,13 @@ func (this *MessageModel) num() int {
} }
func (this *MessageModel) getMessage(idx int) *MessageWrapper { func (this *MessageModel) getMessage(idx int) *MessageWrapper {
modelmsg := model.Message{Message:"[an unexpected cwtch error occurred]"} modelmsg := model.Message{Message: "[an unexpected cwtch error occurred]"}
var ackd bool var ackd bool
if this.isGroup() { if this.isGroup() {
group := the.Peer.GetGroup(this.Handle()) group := the.Peer.GetGroup(this.Handle())
if idx >= len(group.Timeline.Messages) { if idx >= len(group.Timeline.Messages) {
modelmsg = group.UnacknowledgedMessages[idx - len(group.Timeline.Messages)] modelmsg = group.UnacknowledgedMessages[idx-len(group.Timeline.Messages)]
} else { } else {
modelmsg = group.Timeline.Messages[idx] modelmsg = group.Timeline.Messages[idx]
ackd = true ackd = true
@ -134,15 +133,15 @@ func (this *MessageModel) getMessage(idx int) *MessageWrapper {
} }
} }
return &MessageWrapper { return &MessageWrapper{
Message: modelmsg, Message: modelmsg,
Timestamp: modelmsg.Timestamp.Unix(), Timestamp: modelmsg.Timestamp.Unix(),
RawMessage: modelmsg.Message, RawMessage: modelmsg.Message,
PeerID: modelmsg.PeerID, PeerID: modelmsg.PeerID,
Error: modelmsg.Error, Error: modelmsg.Error,
Acknowledged: ackd, Acknowledged: ackd,
Day: modelmsg.Timestamp.Format("January 2, 2006"), Day: modelmsg.Timestamp.Format("January 2, 2006"),
Signature: hex.EncodeToString(modelmsg.Signature), Signature: hex.EncodeToString(modelmsg.Signature),
} }
} }

View File

@ -21,16 +21,16 @@ type GlobalSettings struct {
Theme string Theme string
PreviousPid int64 PreviousPid int64
ExperimentsEnabled bool ExperimentsEnabled bool
Experiments map[string]bool Experiments map[string]bool
} }
var DefaultGlobalSettings = GlobalSettings{ var DefaultGlobalSettings = GlobalSettings{
Zoom: 1.9, Zoom: 1.9,
Locale: "en", Locale: "en",
Theme: "light", Theme: "light",
PreviousPid: -1, PreviousPid: -1,
ExperimentsEnabled: false, ExperimentsEnabled: false,
Experiments: make(map[string]bool), Experiments: make(map[string]bool),
} }
func InitGlobalSettingsFile(directory string, password string) error { func InitGlobalSettingsFile(directory string, password string) error {
@ -68,7 +68,6 @@ func ReadGlobalSettings() (*GlobalSettings, bool) {
return &settings, true //firstTime = true return &settings, true //firstTime = true
} }
err = json.Unmarshal(settingsBytes, &settings) err = json.Unmarshal(settingsBytes, &settings)
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)