migrate to new cwtch authorizations + add new peer and blocked peer workflows to contact list #308

Merged
sarah merged 3 commits from :03-approveBlock into master 2020-07-20 23:53:54 +00:00
24 changed files with 384 additions and 178 deletions

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{fill:#BCB6BC;}
</style>
<path class="st0" d="M0,0h24v24H0V0z"/>
<g>
<path class="st0" d="M12,5c-1.7,0-3,1.3-3,3s1.3,3,3,3c0.1,0,0.1,0,0.1,0l2.7-4C14.4,5.8,13.3,5,12,5z"/>
<path class="st0" d="M12,19.2c2.5,0,4.7-1.3,6-3.2c0-1.7-3.1-2.8-5.2-3l-3.8,5.6C10,19,11,19.2,12,19.2z"/>
<path class="st0" d="M6,16c0.4,0.7,1,1.2,1.6,1.7l3.2-4.7C8.7,13.3,6,14.3,6,16z"/>
<path class="st1" d="M6,16c0-1.6,2.7-2.7,4.8-3l1.4-2c-0.1,0-0.1,0-0.1,0c-1.7,0-3-1.3-3-3s1.3-3,3-3c1.3,0,2.4,0.8,2.8,2l2.4-3.5
C15.7,2.5,13.9,2,12,2C6.5,2,2,6.5,2,12c0,3.3,1.6,6.2,4.1,8l1.6-2.3C7,17.2,6.4,16.6,6,16z"/>
<path class="st1" d="M18.5,4.4L12.8,13c2.1,0.2,5.1,1.3,5.2,3c-1.3,1.9-3.5,3.2-6,3.2c-1,0-2-0.2-2.9-0.6l-1.6,2.4
C8.8,21.6,10.4,22,12,22c5.5,0,10-4.5,10-10C22,9,20.7,6.3,18.5,4.4z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

7
go.mod
View File

@ -3,12 +3,13 @@ module cwtch.im/ui
go 1.12 go 1.12
require ( require (
cwtch.im/cwtch v0.3.11 cwtch.im/cwtch v0.3.15
git.openprivacy.ca/openprivacy/connectivity v1.1.4 git.openprivacy.ca/openprivacy/connectivity v1.1.4
git.openprivacy.ca/openprivacy/log v1.0.0 git.openprivacy.ca/openprivacy/log v1.0.1
github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d // indirect github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d // indirect
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
golang.org/x/crypto v0.0.0-20200320181102-891825fb96df golang.org/x/crypto v0.0.0-20200420104511-884d27f42877 // indirect
) )

6
go.sum
View File

@ -2,6 +2,10 @@ cwtch.im/cwtch v0.3.10 h1:akrIwsc1KnLbT3K6ZIFkhmA7kI62L03EWna7Ul1vszU=
cwtch.im/cwtch v0.3.10/go.mod h1:tmYeI2v0IEeBMbqzhcndXWZ2oyflhK4Afcf27+49rKU= 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 h1:2+W2w9HDQowKwEGx4oRLywmn0NzQ0Sg9JEyBdR/V1mA=
cwtch.im/cwtch v0.3.11/go.mod h1:PnMJb9CyzdrdbYjmL99pl6Nu34s6+lmeENVnGaY0hzk= cwtch.im/cwtch v0.3.11/go.mod h1:PnMJb9CyzdrdbYjmL99pl6Nu34s6+lmeENVnGaY0hzk=
cwtch.im/cwtch v0.3.14 h1:XL8UbCUyIosdFTD5nSlpvhbQQGFLjvFmd81/SmfBSP8=
cwtch.im/cwtch v0.3.14/go.mod h1:wDmgxWBWak/xvZ5GurdYNOJ8b8eha1MwVdiWsCS/pwI=
cwtch.im/cwtch v0.3.15 h1:Z7fFREwXY728q2YmmwgHL357zAobrsWJ2oPkkGwzvo0=
cwtch.im/cwtch v0.3.15/go.mod h1:iI9q4C3njHFBYQkNEbzMdK6QWPS0Vbkc0FigRHZNTvM=
cwtch.im/tapir v0.1.15 h1:XSCWOvjmNkzMT2IceFgTBXWGKtYfr3a8o+La1s10OhE= 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.15/go.mod h1:HzezugpEx+nZ3LdyDsl0w6n45IJYnOt8uqldkLWmaqs=
cwtch.im/tapir v0.1.17 h1:2jVZUe1a88tMI4aJPvRTO4Id3NN3PsM62cT5lntEChk= cwtch.im/tapir v0.1.17 h1:2jVZUe1a88tMI4aJPvRTO4Id3NN3PsM62cT5lntEChk=
@ -23,6 +27,8 @@ git.openprivacy.ca/openprivacy/libricochet-go v1.0.13 h1:Z86uL9K47onznY1wP1P/wWf
git.openprivacy.ca/openprivacy/libricochet-go v1.0.13/go.mod h1:ZUuX1SOrgV4K18IEcp0hQJNPKszRr2oGb3UeK2iYe5U= git.openprivacy.ca/openprivacy/libricochet-go v1.0.13/go.mod h1:ZUuX1SOrgV4K18IEcp0hQJNPKszRr2oGb3UeK2iYe5U=
git.openprivacy.ca/openprivacy/log v1.0.0 h1:Rvqm1weUdR4AOnJ79b1upHCc9vC/QF1rhSD2Um7sr1Y= git.openprivacy.ca/openprivacy/log v1.0.0 h1:Rvqm1weUdR4AOnJ79b1upHCc9vC/QF1rhSD2Um7sr1Y=
git.openprivacy.ca/openprivacy/log v1.0.0/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= git.openprivacy.ca/openprivacy/log v1.0.0/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw=
git.openprivacy.ca/openprivacy/log v1.0.1 h1:NWV5oBTatvlSzUE6wtB+UQCulgyMOtm4BXGd34evMys=
git.openprivacy.ca/openprivacy/log v1.0.1/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw=
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI= 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/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/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=

View File

@ -5,6 +5,7 @@ const SchemaVersion = "schemaVersion"
const Name = "name" const Name = "name"
const LastRead = "last-read" const LastRead = "last-read"
const Picture = "picture" const Picture = "picture"
const ShowBlocked = "show-blocked"
const ProfileTypeV1DefaultPassword = "v1-defaultPassword" const ProfileTypeV1DefaultPassword = "v1-defaultPassword"
const ProfileTypeV1Password = "v1-userPassword" const ProfileTypeV1Password = "v1-userPassword"

View File

@ -3,6 +3,7 @@ package handlers
import ( import (
"cwtch.im/cwtch/app" "cwtch.im/cwtch/app"
"cwtch.im/cwtch/event" "cwtch.im/cwtch/event"
"cwtch.im/cwtch/model"
"cwtch.im/cwtch/model/attr" "cwtch.im/cwtch/model/attr"
peerC "cwtch.im/cwtch/peer" peerC "cwtch.im/cwtch/peer"
"cwtch.im/cwtch/protocol/connections" "cwtch.im/cwtch/protocol/connections"
@ -77,13 +78,12 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) {
case event.PeerStateChange: case event.PeerStateChange:
cxnState := connections.ConnectionStateToType[e.Data[event.ConnectionState]] cxnState := connections.ConnectionStateToType[e.Data[event.ConnectionState]]
// if it's not in the.PeerHandler it's new. Only add once Authed // New connection established
if contact := peer.GetContact(e.Data[event.RemotePeer]); contact == nil { if cxnState == connections.AUTHENTICATED {
// Contact does not exist, we will add them but we won't know who they are until they are authenticated // if it's not in the peer it's new
// So if we get any other state from an unknown contact we do nothing if contact := peer.GetContact(e.Data[event.RemotePeer]); contact == nil {
// (the next exists check will fail) // Contact does not exist, we will add them
if cxnState == connections.AUTHENTICATED { peer.AddContact(e.Data[event.RemotePeer], e.Data[event.RemotePeer], model.AuthUnknown)
peer.AddContact(e.Data[event.RemotePeer], e.Data[event.RemotePeer], false)
uiManager.AddContact(e.Data[event.RemotePeer]) uiManager.AddContact(e.Data[event.RemotePeer])
} }
} }

View File

@ -3,6 +3,7 @@ package ui
import ( import (
"cwtch.im/cwtch/app" "cwtch.im/cwtch/app"
"cwtch.im/cwtch/event" "cwtch.im/cwtch/event"
"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"
@ -52,14 +53,13 @@ type GrandCentralDispatcher struct {
_ func(failed bool) `signal:"ChangePasswordResponse"` _ func(failed bool) `signal:"ChangePasswordResponse"`
// contact list stuff // contact list stuff
_ func(handle, displayName, image string, badge, status int, blocked bool, 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"`
_ func(handle, image string) `signal:"UpdateContactPicture"` _ func(handle, image string) `signal:"UpdateContactPicture"`
_ func(handle string, status int, loading bool) `signal:"UpdateContactStatus"` _ func(handle string, status int, loading bool) `signal:"UpdateContactStatus"`
_ func(handle string, blocked bool) `signal:"UpdateContactBlocked"` _ func(handle string) `signal:"IncContactUnreadCount"`
_ func(handle string) `signal:"IncContactUnreadCount"` _ func(handle string) `signal:"RemoveContact"`
_ func(handle string) `signal:"RemoveContact"` _ func(handle, key, value string) `signal:"UpdateContactAttribute"`
_ func(handle, key, value string) `signal:"UpdateContactAttribute"`
// messages pane stuff // messages pane stuff
_ func(handle, from, displayName, message, image string, mID string, fromMe bool, ts string, ackd bool, error bool) `signal:"AppendMessage"` _ func(handle, from, displayName, message, image string, mID string, fromMe bool, ts string, ackd bool, error bool) `signal:"AppendMessage"`
@ -72,14 +72,14 @@ type GrandCentralDispatcher struct {
_ func(loading bool) `signal:"SetLoadingState"` _ func(loading bool) `signal:"SetLoadingState"`
// profile-area stuff // profile-area stuff
_ func(name, onion, image, tag string) `signal:"UpdateMyProfile"` _ func(name, onion, image, tag, showBlocked string) `signal:"UpdateMyProfile"`
_ func(status int) `signal:"TorStatus"` _ func(status int) `signal:"TorStatus"`
// settings helpers // settings helpers
_ func(str string) `signal:"InvokePopup"` _ func(str string) `signal:"InvokePopup"`
_ func(locale string, zoom float32, theme string) `signal:"SupplySettings"` _ func(locale string, zoom float32, theme string) `signal:"SupplySettings"`
_ func(groupID, name, server, invitation string, accepted bool, addrbooknames, addrbookaddrs []string) `signal:"SupplyGroupSettings"` _ func(groupID, name, server, invitation string, accepted bool, addrbooknames, addrbookaddrs []string) `signal:"SupplyGroupSettings"`
_ func(onion, nick string, blocked bool) `signal:"SupplyPeerSettings"` _ func(onion, nick string, authorization string) `signal:"SupplyPeerSettings"`
// signals emitted from the ui (written in go, below) // signals emitted from the ui (written in go, below)
// ui // ui
@ -92,10 +92,10 @@ type GrandCentralDispatcher struct {
_ func() `signal:"reloadProfileList,auto"` _ func() `signal:"reloadProfileList,auto"`
_ func(onion string) `signal:"deleteProfile,auto"` _ func(onion string) `signal:"deleteProfile,auto"`
_ func(onion, currentPassword, newPassword string, defaultPass bool) `signal:"changePassword,auto""` _ func(onion, currentPassword, newPassword string, defaultPass bool) `signal:"changePassword,auto""`
_ func(key, val string) `signal:"storeSetting,auto"`
// operating a profile // operating a profile
_ func(message string, mid string) `signal:"sendMessage,auto"` _ func(message string, mid string) `signal:"sendMessage,auto"`
_ func(onion string) `signal:"blockPeer,auto"` _ func(onion string, auth string) `signal:"setPeerAuthorization,auto"`
_ func(onion string) `signal:"unblockPeer,auto"`
_ func(onion string) `signal:"loadMessagesPane,auto"` _ func(onion string) `signal:"loadMessagesPane,auto"`
_ func(signal string) `signal:"broadcast,auto"` // convenience relay signal _ func(signal string) `signal:"broadcast,auto"` // convenience relay signal
_ func(str string) `signal:"importString,auto"` _ func(str string) `signal:"importString,auto"`
@ -339,7 +339,7 @@ func (this *GrandCentralDispatcher) requestPeerSettings() {
contact := the.Peer.GetContact(this.SelectedConversation()) contact := the.Peer.GetContact(this.SelectedConversation())
if contact == nil { if contact == nil {
log.Errorf("error: requested settings for unknown contact %v?", this.SelectedConversation()) log.Errorf("error: requested settings for unknown contact %v?", this.SelectedConversation())
this.SupplyPeerSettings(this.SelectedConversation(), this.SelectedConversation(), false) this.SupplyPeerSettings(this.SelectedConversation(), this.SelectedConversation(), string(contact.Authorization))
return return
} }
@ -348,7 +348,7 @@ func (this *GrandCentralDispatcher) requestPeerSettings() {
// Todo: Move to profile settings // Todo: Move to profile settings
//blockunkownpeers, _ := the.Peer.GetAttribute(attr.GetPeerScope(constants.BlockUnknownPeersSetting)) //blockunkownpeers, _ := the.Peer.GetAttribute(attr.GetPeerScope(constants.BlockUnknownPeersSetting))
this.SupplyPeerSettings(contact.Onion, name, contact.Blocked) this.SupplyPeerSettings(contact.Onion, name, string(contact.Authorization))
} }
func (this *GrandCentralDispatcher) savePeerSettings(onion, nick string) { func (this *GrandCentralDispatcher) savePeerSettings(onion, nick string) {
@ -397,7 +397,7 @@ func (this *GrandCentralDispatcher) createContact(onion string) {
if contact := the.Peer.GetContact(onion); contact != nil { if contact := the.Peer.GetContact(onion); contact != nil {
return return
} }
the.Peer.AddContact(onion, onion, false) the.Peer.AddContact(onion, onion, model.AuthApproved)
the.Peer.PeerWithOnion(onion) the.Peer.PeerWithOnion(onion)
} }
@ -460,7 +460,7 @@ func (this *GrandCentralDispatcher) importString(str string) {
this.InvokePopup("already have this contact") this.InvokePopup("already have this contact")
return //TODO: bring them to the duplicate return //TODO: bring them to the duplicate
} else { } else {
the.Peer.AddContact(name, onion, false) the.Peer.AddContact(name, onion, model.AuthApproved)
the.Peer.PeerWithOnion(onion) the.Peer.PeerWithOnion(onion)
} }
@ -496,21 +496,18 @@ func (this *GrandCentralDispatcher) createGroup(server, groupName string) {
the.Peer.JoinServer(server) the.Peer.JoinServer(server)
} }
func (this *GrandCentralDispatcher) blockPeer(onion string) { func (this *GrandCentralDispatcher) setPeerAuthorization(onion string, authorization string) {
err := the.Peer.BlockPeer(onion) log.Debugf("Setting peer auth level to %v for %v\n", authorization, onion)
err := the.Peer.SetContactAuthorization(onion, model.Authorization(authorization))
if err != nil { if err != nil {
this.InvokePopup("Error Blocking Peer: " + err.Error()) log.Errorf("Could not set peer authorization %v to %v\n", onion, authorization)
return
} }
this.UpdateContactBlocked(onion, true) this.RemoveContact(onion)
} this.GetUiManager(this.selectedProfile()).AddContact(onion)
if model.Authorization(authorization) == model.AuthApproved {
func (this *GrandCentralDispatcher) unblockPeer(onion string) { the.Peer.PeerWithOnion(onion)
err := the.Peer.UnblockPeer(onion)
if err != nil {
this.InvokePopup("Error Unblocking Peer: " + err.Error())
} }
the.Peer.PeerWithOnion(onion)
this.UpdateContactBlocked(onion, false)
} }
func (this *GrandCentralDispatcher) inviteToGroup(onion, groupID string) { func (this *GrandCentralDispatcher) inviteToGroup(onion, groupID string) {
@ -622,7 +619,12 @@ func (this *GrandCentralDispatcher) loadProfile(onion string) {
the.Peer.SetAttribute(attr.GetPublicScope(constants.Picture), ImageToString(pic)) the.Peer.SetAttribute(attr.GetPublicScope(constants.Picture), ImageToString(pic))
} }
tag, _ := the.Peer.GetAttribute(app.AttributeTag) tag, _ := the.Peer.GetAttribute(app.AttributeTag)
this.UpdateMyProfile(the.Peer.GetName(), the.Peer.GetOnion(), getPicturePath(pic), tag) showBlocked, exists := the.Peer.GetAttribute(attr.GetSettingsScope(constants.ShowBlocked))
if !exists {
showBlocked = "false"
the.Peer.SetAttribute(attr.GetSettingsScope(constants.ShowBlocked), showBlocked)
}
this.UpdateMyProfile(the.Peer.GetName(), the.Peer.GetOnion(), getPicturePath(pic), tag, showBlocked)
contacts := the.Peer.GetContacts() contacts := the.Peer.GetContacts()
for i := range contacts { for i := range contacts {
@ -658,6 +660,10 @@ func (this *GrandCentralDispatcher) changePassword(onion, currentPassword, newPa
the.CwtchApp.ChangePeerPassword(onion, currentPassword, newPassword) the.CwtchApp.ChangePeerPassword(onion, currentPassword, newPassword)
} }
func (this *GrandCentralDispatcher) storeSetting(key, val string) {
the.Peer.SetAttribute(attr.GetSettingsScope(key), val)
}
func (this *GrandCentralDispatcher) reloadProfileList() { func (this *GrandCentralDispatcher) reloadProfileList() {
this.ResetProfileList() this.ResetProfileList()

View File

@ -123,7 +123,7 @@ func getProfilePic(id string) string {
return getPicturePath(pic) return getPicturePath(pic)
} }
} }
return getPicturePath(NewImage("fontawesome/regular/user.svg", TypeImageDistro)) return RandomProfileImage(id)
} }
} }
@ -241,7 +241,7 @@ func (this *manager) AddContact(handle string) {
unread := countUnread(group.Timeline.GetMessages(), lastRead) unread := countUnread(group.Timeline.GetMessages(), lastRead)
picture := getProfilePic(handle) picture := getProfilePic(handle)
this.gcd.AddContact(handle, getNick(handle), picture, unread, int(connections.ConnectionStateToType[group.State]), false, false, getLastMessageTime(&group.Timeline)) this.gcd.AddContact(handle, getNick(handle), picture, unread, int(connections.ConnectionStateToType[group.State]), string(model.AuthApproved), false, getLastMessageTime(&group.Timeline))
} }
return return
} else if !isPeer(handle) { } else if !isPeer(handle) {
@ -256,7 +256,7 @@ func (this *manager) AddContact(handle string) {
unread := countUnread(contact.Timeline.GetMessages(), lastRead) unread := countUnread(contact.Timeline.GetMessages(), lastRead)
picture := getProfilePic(handle) picture := getProfilePic(handle)
this.gcd.AddContact(handle, getNick(handle), 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]), string(contact.Authorization), false, getLastMessageTime(&contact.Timeline))
} }
}) })
} }

View File

@ -1,15 +1,11 @@
package ui package ui
import ( import (
"crypto/rand"
"cwtch.im/cwtch/storage/v1" "cwtch.im/cwtch/storage/v1"
"cwtch.im/ui/go/the" "cwtch.im/ui/go/the"
"encoding/json" "encoding/json"
"git.openprivacy.ca/openprivacy/log" "git.openprivacy.ca/openprivacy/log"
"github.com/therecipe/qt/core" "github.com/therecipe/qt/core"
"golang.org/x/crypto/pbkdf2"
"golang.org/x/crypto/sha3"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"path" "path"
@ -31,34 +27,12 @@ var DefaultGlobalSettings = GlobalSettings{
Theme: "light", Theme: "light",
} }
// createKeySalt derives a key from a password: returns key, salt, err
func createKeySalt(password string) ([32]byte, [128]byte, error) {
var salt [128]byte
if _, err := io.ReadFull(rand.Reader, salt[:]); err != nil {
log.Errorf("Cannot read from random: %v\n", err)
return [32]byte{}, salt, err
}
dk := pbkdf2.Key([]byte(password), salt[:], 4096, 32, sha3.New512)
var dkr [32]byte
copy(dkr[:], dk)
return dkr, salt, nil
}
func createKey(password string, salt []byte) [32]byte {
dk := pbkdf2.Key([]byte(password), salt, 4096, 32, sha3.New512)
var dkr [32]byte
copy(dkr[:], dk)
return dkr
}
func InitGlobalSettingsFile(directory string, password string) error { func InitGlobalSettingsFile(directory string, password string) error {
var key [32]byte var key [32]byte
salt, err := ioutil.ReadFile(path.Join(directory, saltFile)) salt, err := ioutil.ReadFile(path.Join(directory, saltFile))
if err != nil { if err != nil {
var newSalt [128]byte var newSalt [128]byte
key, newSalt, err = createKeySalt(password) key, newSalt, err = v1.CreateKeySalt(password)
if err != nil { if err != nil {
return err return err
} }
@ -68,7 +42,7 @@ func InitGlobalSettingsFile(directory string, password string) error {
return err return err
} }
} else { } else {
key = createKey(password, salt) key = v1.CreateKey(password, salt)
} }
the.GlobalSettingsFile = v1.NewFileStore(directory, GlobalSettingsFilename, key) the.GlobalSettingsFile = v1.NewFileStore(directory, GlobalSettingsFilename, key)

View File

@ -55,11 +55,16 @@
<context> <context>
<name>ContactList</name> <name>ContactList</name>
<message> <message>
<location filename="../qml/widgets/ContactList.qml" line="41"/> <location filename="../qml/widgets/ContactList.qml" line="53"/>
<source>paste-address-to-add-contact</source> <source>paste-address-to-add-contact</source>
<extracomment>ex: &quot;... paste an address here to add a contact ...&quot;</extracomment> <extracomment>ex: &quot;... paste an address here to add a contact ...&quot;</extracomment>
<translation type="unfinished">Adresse hier hinzufügen, um einen Kontakt aufzunehmen</translation> <translation type="unfinished">Adresse hier hinzufügen, um einen Kontakt aufzunehmen</translation>
</message> </message>
<message>
<location filename="../qml/widgets/ContactList.qml" line="251"/>
<source>blocked</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>GroupSettingsPane</name> <name>GroupSettingsPane</name>
@ -227,38 +232,38 @@
<context> <context>
<name>PeerSettingsPane</name> <name>PeerSettingsPane</name>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="25"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="26"/>
<source>address-label</source> <source>address-label</source>
<translation>Adresse</translation> <translation>Adresse</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="30"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="31"/>
<source>copy-btn</source> <source>copy-btn</source>
<translation>Kopieren</translation> <translation>Kopieren</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="34"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="35"/>
<source>copied-to-clipboard-notification</source> <source>copied-to-clipboard-notification</source>
<extracomment>notification: copied to clipboard</extracomment> <extracomment>notification: copied to clipboard</extracomment>
<translation>in die Zwischenablage kopiert</translation> <translation>in die Zwischenablage kopiert</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="46"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="47"/>
<source>display-name-label</source> <source>display-name-label</source>
<translation>Angezeigter Name</translation> <translation>Angezeigter Name</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="50"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="51"/>
<source>save-btn</source> <source>save-btn</source>
<translation>speichern</translation> <translation>speichern</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="89"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="92"/>
<source>delete-btn</source> <source>delete-btn</source>
<translation>löschen</translation> <translation>löschen</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="65"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="64"/>
<source>block-btn</source> <source>block-btn</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -371,7 +376,7 @@
<context> <context>
<name>ProfileList</name> <name>ProfileList</name>
<message> <message>
<location filename="../qml/widgets/ProfileList.qml" line="108"/> <location filename="../qml/widgets/ProfileList.qml" line="107"/>
<source>add-new-profile-btn</source> <source>add-new-profile-btn</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -447,34 +452,34 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="84"/> <location filename="../qml/panes/SettingsPane.qml" line="86"/>
<source>large-text-label</source> <source>large-text-label</source>
<translation>Groß</translation> <translation>Groß</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="92"/> <location filename="../qml/panes/SettingsPane.qml" line="94"/>
<source>setting-theme</source> <source>setting-theme</source>
<extracomment>Theme</extracomment> <extracomment>Theme</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="101"/> <location filename="../qml/panes/SettingsPane.qml" line="103"/>
<source>theme-light</source> <source>theme-light</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="102"/> <location filename="../qml/panes/SettingsPane.qml" line="104"/>
<source>theme-dark</source> <source>theme-dark</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="151"/> <location filename="../qml/panes/SettingsPane.qml" line="153"/>
<source>version %1</source> <source>version %1</source>
<extracomment>Version %1</extracomment> <extracomment>Version %1</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="160"/> <location filename="../qml/panes/SettingsPane.qml" line="162"/>
<source>builddate %2</source> <source>builddate %2</source>
<extracomment>Built on: %2</extracomment> <extracomment>Built on: %2</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>

Binary file not shown.

View File

@ -55,11 +55,16 @@
<context> <context>
<name>ContactList</name> <name>ContactList</name>
<message> <message>
<location filename="../qml/widgets/ContactList.qml" line="41"/> <location filename="../qml/widgets/ContactList.qml" line="53"/>
<source>paste-address-to-add-contact</source> <source>paste-address-to-add-contact</source>
<extracomment>ex: &quot;... paste an address here to add a contact ...&quot;</extracomment> <extracomment>ex: &quot;... paste an address here to add a contact ...&quot;</extracomment>
<translation>... paste an address here to add a contact...</translation> <translation>... paste an address here to add a contact...</translation>
</message> </message>
<message>
<location filename="../qml/widgets/ContactList.qml" line="251"/>
<source>blocked</source>
<translation>Blocked</translation>
</message>
</context> </context>
<context> <context>
<name>EmojiDrawer</name> <name>EmojiDrawer</name>
@ -322,33 +327,33 @@ Right-click to reset.</translation>
<context> <context>
<name>PeerSettingsPane</name> <name>PeerSettingsPane</name>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="25"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="26"/>
<source>address-label</source> <source>address-label</source>
<translation>Address</translation> <translation>Address</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="30"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="31"/>
<source>copy-btn</source> <source>copy-btn</source>
<translation>Copy</translation> <translation>Copy</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="34"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="35"/>
<source>copied-to-clipboard-notification</source> <source>copied-to-clipboard-notification</source>
<extracomment>notification: copied to clipboard</extracomment> <extracomment>notification: copied to clipboard</extracomment>
<translation>Copied to Clipboard</translation> <translation>Copied to Clipboard</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="46"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="47"/>
<source>display-name-label</source> <source>display-name-label</source>
<translation>Display Name</translation> <translation>Display Name</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="50"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="51"/>
<source>save-btn</source> <source>save-btn</source>
<translation>Save</translation> <translation>Save</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="65"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="64"/>
<source>block-btn</source> <source>block-btn</source>
<translation>Block Peer</translation> <translation>Block Peer</translation>
</message> </message>
@ -357,7 +362,7 @@ Right-click to reset.</translation>
<translation type="vanished">Unblock Peer</translation> <translation type="vanished">Unblock Peer</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="89"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="92"/>
<source>delete-btn</source> <source>delete-btn</source>
<translation>Delete</translation> <translation>Delete</translation>
</message> </message>
@ -478,7 +483,7 @@ Right-click to reset.</translation>
<context> <context>
<name>ProfileList</name> <name>ProfileList</name>
<message> <message>
<location filename="../qml/widgets/ProfileList.qml" line="108"/> <location filename="../qml/widgets/ProfileList.qml" line="107"/>
<source>add-new-profile-btn</source> <source>add-new-profile-btn</source>
<translation>Add new profile</translation> <translation>Add new profile</translation>
</message> </message>
@ -563,34 +568,34 @@ Right-click to reset.</translation>
<translation>Zoom level</translation> <translation>Zoom level</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="84"/> <location filename="../qml/panes/SettingsPane.qml" line="86"/>
<source>large-text-label</source> <source>large-text-label</source>
<translation>Large</translation> <translation>Large</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="92"/> <location filename="../qml/panes/SettingsPane.qml" line="94"/>
<source>setting-theme</source> <source>setting-theme</source>
<extracomment>Theme</extracomment> <extracomment>Theme</extracomment>
<translation>Theme</translation> <translation>Theme</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="101"/> <location filename="../qml/panes/SettingsPane.qml" line="103"/>
<source>theme-light</source> <source>theme-light</source>
<translation>Light</translation> <translation>Light</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="102"/> <location filename="../qml/panes/SettingsPane.qml" line="104"/>
<source>theme-dark</source> <source>theme-dark</source>
<translation>Dark</translation> <translation>Dark</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="151"/> <location filename="../qml/panes/SettingsPane.qml" line="153"/>
<source>version %1</source> <source>version %1</source>
<extracomment>Version %1</extracomment> <extracomment>Version %1</extracomment>
<translation>Version %1</translation> <translation>Version %1</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="160"/> <location filename="../qml/panes/SettingsPane.qml" line="162"/>
<source>builddate %2</source> <source>builddate %2</source>
<extracomment>Built on: %2</extracomment> <extracomment>Built on: %2</extracomment>
<translation>Built on: %2</translation> <translation>Built on: %2</translation>

View File

@ -55,11 +55,16 @@
<context> <context>
<name>ContactList</name> <name>ContactList</name>
<message> <message>
<location filename="../qml/widgets/ContactList.qml" line="41"/> <location filename="../qml/widgets/ContactList.qml" line="53"/>
<source>paste-address-to-add-contact</source> <source>paste-address-to-add-contact</source>
<extracomment>ex: &quot;... paste an address here to add a contact ...&quot;</extracomment> <extracomment>ex: &quot;... paste an address here to add a contact ...&quot;</extracomment>
<translation type="unfinished">... coller une adresse ici pour ajouter un contact...</translation> <translation type="unfinished">... coller une adresse ici pour ajouter un contact...</translation>
</message> </message>
<message>
<location filename="../qml/widgets/ContactList.qml" line="251"/>
<source>blocked</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>GroupSettingsPane</name> <name>GroupSettingsPane</name>
@ -227,38 +232,38 @@
<context> <context>
<name>PeerSettingsPane</name> <name>PeerSettingsPane</name>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="25"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="26"/>
<source>address-label</source> <source>address-label</source>
<translation>Adresse</translation> <translation>Adresse</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="30"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="31"/>
<source>copy-btn</source> <source>copy-btn</source>
<translation>Copier</translation> <translation>Copier</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="34"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="35"/>
<source>copied-to-clipboard-notification</source> <source>copied-to-clipboard-notification</source>
<extracomment>notification: copied to clipboard</extracomment> <extracomment>notification: copied to clipboard</extracomment>
<translation>Copié dans le presse-papier</translation> <translation>Copié dans le presse-papier</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="46"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="47"/>
<source>display-name-label</source> <source>display-name-label</source>
<translation>Pseudo</translation> <translation>Pseudo</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="50"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="51"/>
<source>save-btn</source> <source>save-btn</source>
<translation>Sauvegarder</translation> <translation>Sauvegarder</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="89"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="92"/>
<source>delete-btn</source> <source>delete-btn</source>
<translation>Effacer</translation> <translation>Effacer</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="65"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="64"/>
<source>block-btn</source> <source>block-btn</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -371,7 +376,7 @@
<context> <context>
<name>ProfileList</name> <name>ProfileList</name>
<message> <message>
<location filename="../qml/widgets/ProfileList.qml" line="108"/> <location filename="../qml/widgets/ProfileList.qml" line="107"/>
<source>add-new-profile-btn</source> <source>add-new-profile-btn</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -447,34 +452,34 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="84"/> <location filename="../qml/panes/SettingsPane.qml" line="86"/>
<source>large-text-label</source> <source>large-text-label</source>
<translation type="unfinished">Large</translation> <translation type="unfinished">Large</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="92"/> <location filename="../qml/panes/SettingsPane.qml" line="94"/>
<source>setting-theme</source> <source>setting-theme</source>
<extracomment>Theme</extracomment> <extracomment>Theme</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="101"/> <location filename="../qml/panes/SettingsPane.qml" line="103"/>
<source>theme-light</source> <source>theme-light</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="102"/> <location filename="../qml/panes/SettingsPane.qml" line="104"/>
<source>theme-dark</source> <source>theme-dark</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="151"/> <location filename="../qml/panes/SettingsPane.qml" line="153"/>
<source>version %1</source> <source>version %1</source>
<extracomment>Version %1</extracomment> <extracomment>Version %1</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="160"/> <location filename="../qml/panes/SettingsPane.qml" line="162"/>
<source>builddate %2</source> <source>builddate %2</source>
<extracomment>Built on: %2</extracomment> <extracomment>Built on: %2</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>

View File

@ -55,11 +55,16 @@
<context> <context>
<name>ContactList</name> <name>ContactList</name>
<message> <message>
<location filename="../qml/widgets/ContactList.qml" line="41"/> <location filename="../qml/widgets/ContactList.qml" line="53"/>
<source>paste-address-to-add-contact</source> <source>paste-address-to-add-contact</source>
<extracomment>ex: &quot;... paste an address here to add a contact ...&quot;</extracomment> <extracomment>ex: &quot;... paste an address here to add a contact ...&quot;</extracomment>
<translation type="unfinished"> cole um endereço aqui para adicionar um contato</translation> <translation type="unfinished"> cole um endereço aqui para adicionar um contato</translation>
</message> </message>
<message>
<location filename="../qml/widgets/ContactList.qml" line="251"/>
<source>blocked</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>GroupSettingsPane</name> <name>GroupSettingsPane</name>
@ -227,38 +232,38 @@
<context> <context>
<name>PeerSettingsPane</name> <name>PeerSettingsPane</name>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="25"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="26"/>
<source>address-label</source> <source>address-label</source>
<translation>Endereço</translation> <translation>Endereço</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="30"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="31"/>
<source>copy-btn</source> <source>copy-btn</source>
<translation>Copiar</translation> <translation>Copiar</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="34"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="35"/>
<source>copied-to-clipboard-notification</source> <source>copied-to-clipboard-notification</source>
<extracomment>notification: copied to clipboard</extracomment> <extracomment>notification: copied to clipboard</extracomment>
<translation>Copiado</translation> <translation>Copiado</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="46"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="47"/>
<source>display-name-label</source> <source>display-name-label</source>
<translation>Nome de Exibição</translation> <translation>Nome de Exibição</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="50"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="51"/>
<source>save-btn</source> <source>save-btn</source>
<translation>Salvar</translation> <translation>Salvar</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="89"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="92"/>
<source>delete-btn</source> <source>delete-btn</source>
<translation>Deletar</translation> <translation>Deletar</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/PeerSettingsPane.qml" line="65"/> <location filename="../qml/panes/PeerSettingsPane.qml" line="64"/>
<source>block-btn</source> <source>block-btn</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -371,7 +376,7 @@
<context> <context>
<name>ProfileList</name> <name>ProfileList</name>
<message> <message>
<location filename="../qml/widgets/ProfileList.qml" line="108"/> <location filename="../qml/widgets/ProfileList.qml" line="107"/>
<source>add-new-profile-btn</source> <source>add-new-profile-btn</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -447,34 +452,34 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="84"/> <location filename="../qml/panes/SettingsPane.qml" line="86"/>
<source>large-text-label</source> <source>large-text-label</source>
<translation>Grande</translation> <translation>Grande</translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="92"/> <location filename="../qml/panes/SettingsPane.qml" line="94"/>
<source>setting-theme</source> <source>setting-theme</source>
<extracomment>Theme</extracomment> <extracomment>Theme</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="101"/> <location filename="../qml/panes/SettingsPane.qml" line="103"/>
<source>theme-light</source> <source>theme-light</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="102"/> <location filename="../qml/panes/SettingsPane.qml" line="104"/>
<source>theme-dark</source> <source>theme-dark</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="151"/> <location filename="../qml/panes/SettingsPane.qml" line="153"/>
<source>version %1</source> <source>version %1</source>
<extracomment>Version %1</extracomment> <extracomment>Version %1</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../qml/panes/SettingsPane.qml" line="160"/> <location filename="../qml/panes/SettingsPane.qml" line="162"/>
<source>builddate %2</source> <source>builddate %2</source>
<extracomment>Built on: %2</extracomment> <extracomment>Built on: %2</extracomment>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>

14
qml/const/Const.qml Normal file
View File

@ -0,0 +1,14 @@
pragma Singleton
import QtQuick 2.0
Item {
// defined in cwtch.im/cwtch/model/profile.go ln24
readonly property string auth_unknown: "unknown"
readonly property string auth_blocked: "blocked"
readonly property string auth_approved: "approved"
// defined in cwtch.im/ui/go/constants/attributes.go
readonly property string show_blocked: "show-blocked"
}

1
qml/const/qmldir Normal file
View File

@ -0,0 +1 @@
singleton Const 1.0 Const.qml

View File

@ -348,8 +348,6 @@ ApplicationWindow {
if (Qt.application.state == 4) { if (Qt.application.state == 4) {
// Active // Active
gcd.onActivate() gcd.onActivate()
console.log(Fonts.applicationFontRegular.name)
console.log(Fonts.applicationFontBold.name)
} }
} }
} }

@ -1 +1 @@
Subproject commit 0ec6a2df571e1a9c462d902cfc89f2402a9bef97 Subproject commit 0505934172c42fc589f8c0e095e1e8f0efeda245

View File

@ -10,12 +10,13 @@ import QtQuick.Controls.Styles 1.4
import "../opaque" as Opaque import "../opaque" as Opaque
import "../opaque/styles" import "../opaque/styles"
import "../opaque/theme" import "../opaque/theme"
import "../const"
Opaque.SettingsList { // settingsPane Opaque.SettingsList { // settingsPane
id: root id: root
anchors.fill: parent anchors.fill: parent
property bool blocked property string authorization
settings: Column { settings: Column {
anchors.fill: parent anchors.fill: parent
@ -59,8 +60,6 @@ Opaque.SettingsList { // settingsPane
} }
Opaque.Setting { Opaque.Setting {
label: qsTr("block-btn") label: qsTr("block-btn")
@ -68,15 +67,19 @@ Opaque.SettingsList { // settingsPane
field: Opaque.ToggleSwitch { field: Opaque.ToggleSwitch {
anchors.right: parent.right anchors.right: parent.right
isToggled: root.blocked // ? qsTr("unblock-btn") : qsTr("block-btn") isToggled: root.authorization == Const.auth_blocked
onToggled: function() { onToggled: function() {
if (root.blocked) { console.log("peer block toddle for " + txtOnion.text + " currently: " + root.authorization)
gcd.unblockPeer(txtOnion.text) if (root.authorization == Const.auth_blocked) {
root.authorization = Const.auth_unknown
console.log("setPeerAuthorization to " + Const.auth_unknown + " for " + txtOnion.text)
gcd.setPeerAuthorization(txtOnion.text, Const.auth_unknown)
} else { } else {
gcd.blockPeer(txtOnion.text) root.authorization = Const.auth_blocked
console.log("setPeerAuthorization to " + Const.auth_blocked + " for " + txtOnion.text)
gcd.setPeerAuthorization(txtOnion.text, Const.auth_blocked)
} }
root.blocked = !root.blocked isToggled = root.authorization == Const.auth_blocked
isToggled = root.blocked
} }
} }
} }
@ -103,10 +106,10 @@ Opaque.SettingsList { // settingsPane
Connections { Connections {
target: gcd target: gcd
onSupplyPeerSettings: function(onion, nick, blocked) { onSupplyPeerSettings: function(onion, nick, authorization) {
txtOnion.text = onion txtOnion.text = onion
txtDisplayName.text = nick txtDisplayName.text = nick
root.blocked = blocked root.authorization = authorization
} }
} }

View File

@ -72,6 +72,7 @@ Opaque.SettingsList { // settingsPane
value: gcd.themeScale value: gcd.themeScale
live: false live: false
stepSize: 0.1 stepSize: 0.1
onValueChanged: { onValueChanged: {
gcd.themeScale = zoomSlider.value gcd.themeScale = zoomSlider.value
} }
@ -88,7 +89,6 @@ Opaque.SettingsList { // settingsPane
} }
} }
Opaque.Setting { Opaque.Setting {
//: Theme //: Theme
label: qsTr("setting-theme") label: qsTr("setting-theme")
@ -193,10 +193,6 @@ text: qsTr("block-unknown-label")
} }
} }
} }
*/ */

View File

@ -6,11 +6,13 @@ import QtQuick.Layouts 1.3
import "../opaque" as Opaque import "../opaque" as Opaque
import "../opaque/theme" import "../opaque/theme"
import "../const"
ColumnLayout { ColumnLayout {
id: root id: root
property alias dualPane: myprof.dualPane property alias dualPane: myprof.dualPane
property real logscale: 4 * Math.log10(gcd.themeScale + 1)
spacing: 10 spacing: 10
@ -26,6 +28,16 @@ ColumnLayout {
id: myprof id: myprof
} }
function removeContact(model, handle) {
for(var i = 0; i < model.count; i++){
if(model.get(i)["_handle"] == handle) {
model.remove(i)
return true
}
}
return false
}
Opaque.IconTextField { Opaque.IconTextField {
id: searchAddText id: searchAddText
@ -61,10 +73,9 @@ ColumnLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.minimumWidth: parent.width Layout.minimumWidth: parent.width
Layout.maximumWidth: parent.width Layout.maximumWidth: parent.width
contentWidth: colContacts.width contentWidth: parent.width
contentHeight: colContacts.height contentHeight: colContacts.height
boundsBehavior: Flickable.StopAtBounds boundsBehavior: Flickable.StopAtBounds
maximumFlickVelocity: 400
ScrollBar.vertical: ScrollBar { ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded policy: ScrollBar.AsNeeded
@ -80,6 +91,8 @@ ColumnLayout {
} }
} }
ColumnLayout { ColumnLayout {
id: colContacts id: colContacts
width: root.width width: root.width
@ -88,17 +101,29 @@ ColumnLayout {
Connections { // ADD/REMOVE CONTACT ENTRIES Connections { // ADD/REMOVE CONTACT ENTRIES
target: gcd target: gcd
onAddContact: function(handle, displayName, image, badge, status, blocked, loading, lastMsgTs) { onAddContact: function(handle, displayName, image, badge, status, authorization, loading, lastMsgTs) {
var model = contactsModel
if (authorization == Const.auth_blocked) {
model = blockedContactsModel
}
for (var i = 0; i < contactsModel.count; i++) { for (var i = 0; i < model.count; i++) {
if (contactsModel.get(i)["_handle"] == handle) { if (model.get(i)["_handle"] == handle) {
return return
} }
} }
var index = contactsModel.count // Sort order: [unknown,authed][most recent message]
for (var i = 0; i < contactsModel.count; i++) { var index = model.count
if (contactsModel.get(i)["_lastMsgTs"] < lastMsgTs) { for (var i = 0; i < model.count; i++) {
var contact = model.get(i)
if (contact["_authorization"] == authorization) {
if (contact["_lastMsgTs"] < lastMsgTs) {
index = i
break
}
} else if (authorization == Const.auth_unknown) {
index = i index = i
break break
} }
@ -106,26 +131,23 @@ ColumnLayout {
var newContact = { var newContact = {
"_handle": handle, "_handle": handle,
"_displayName": displayName + (blocked ? " (blocked)" : "" ), "_displayName": displayName,
"_image": image, "_image": image,
"_badge": badge, "_badge": badge,
"_status": status, "_status": status,
"_blocked": blocked, "_authorization": authorization,
"_loading": loading, "_loading": loading,
"_loading": loading, "_loading": loading,
"_lastMsgTs": lastMsgTs "_lastMsgTs": lastMsgTs
} }
contactsModel.insert(index, newContact) model.insert(index, newContact)
} }
onRemoveContact: function(handle) { onRemoveContact: function(handle) {
for(var i = 0; i < contactsModel.count; i++){ var removed = root.removeContact(contactsModel, handle)
if(contactsModel.get(i)["_handle"] == handle) { if (!removed) {
console.log("deleting contact " + contactsModel.get(i)["_handle"]) root.removeContact(blockedContactsModel, handle)
contactsModel.remove(i)
return
}
} }
} }
@ -142,6 +164,7 @@ ColumnLayout {
onResetProfile: function() { onResetProfile: function() {
contactsModel.clear() contactsModel.clear()
blockedContactsModel.clear()
} }
} }
@ -150,6 +173,7 @@ ColumnLayout {
} }
Repeater { Repeater {
id: contactRepeater
model: contactsModel // ... AND DISPLAYED HERE model: contactsModel // ... AND DISPLAYED HERE
delegate: ContactRow { delegate: ContactRow {
handle: _handle handle: _handle
@ -157,17 +181,122 @@ ColumnLayout {
image: _image image: _image
badge: _badge badge: _badge
status: _status status: _status
blocked: _blocked authorization: _authorization
loading: _loading loading: _loading
rowColor: (_authorization == Const.auth_unknown) ? Theme.backgroundHilightElementColor : Theme.backgroundMainColor
Layout.fillWidth: true
} }
} }
Item {
id: blockItem
height: blockedToggle.height
Layout.fillWidth: true
visible: blockedContactsModel.count > 0
MouseArea {
anchors.fill: blockItem
hoverEnabled: true
onClicked: {
blockedToggle.showing = !blockedToggle.showing
blockedContacts.visible = blockedToggle.showing
if (blockedToggle.showing) {
gcd.storeSetting(Const.show_blocked, "true")
} else {
gcd.storeSetting(Const.show_blocked, "false")
}
}
onEntered: {
blockedBG.color = Theme.backgroundPaneColor
}
onExited: {
blockedBG.color = Theme.backgroundMainColor
}
}
Rectangle {
id: blockedBG
property bool isHover: false
anchors.fill: blockItem
color: Theme.backgroundMainColor
Connections {
target: Theme
onThemeChanged: {
blockedBG.color = Theme.backgroundMainColor
}
}
}
Row {
id: blockedToggle
property bool showing: true
leftPadding: 32 * logscale
topPadding: 16 * logscale
bottomPadding: 8 * logscale
spacing: 5 * logscale
Opaque.ScalingLabel {
id: blockLbl
text: qsTr("blocked")
size: Theme.chatMetaTextSize
color: Theme.portraitBlockedTextColor
}
Opaque.ScalingLabel {
id: blockBtn
text: blockedToggle.showing ? "▲" : "▼"
size: Theme.chatMetaTextSize
color: Theme.portraitBlockedTextColor
}
}
Connections {
target: gcd
onUpdateMyProfile: function(_nick, _onion, _image, _tag, _showBlocked) {
blockedToggle.showing = (_showBlocked == "true")
blockedContacts.visible = (_showBlocked == "true")
}
}
}
ListModel {
id: blockedContactsModel
}
ColumnLayout {
id: blockedContacts
Layout.fillWidth: true
spacing: 0
Repeater {
id: blockedContactsRepeater
model: blockedContactsModel // ... AND DISPLAYED HERE
delegate: ContactRow {
handle: _handle
displayName: _displayName
image: _image
badge: _badge
status: _status
authorization: _authorization
loading: _loading
Layout.fillWidth: true
}
}
}
} }
} }
} }

View File

@ -10,11 +10,16 @@ import QtQuick.Controls.Styles 1.4
import "../opaque" as Opaque import "../opaque" as Opaque
import "../opaque/styles" import "../opaque/styles"
import "../opaque/theme" import "../opaque/theme"
import "../const"
Opaque.PortraitRow { Opaque.PortraitRow {
property int status: 0 property int status: 0
property int badge property int badge
property bool loading property bool loading
property string authorization
// TODO: should be in ContactRow
property bool blocked
badgeColor: Theme.portraitContactBadgeColor badgeColor: Theme.portraitContactBadgeColor
badgeVisible: badge > 0 badgeVisible: badge > 0
@ -48,6 +53,35 @@ Opaque.PortraitRow {
} }
} }
Column {
visible: authorization == Const.auth_unknown
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 1 * gcd.themeScale
anchors.rightMargin: 25 * gcd.themeScale
spacing: 16 * gcd.themeScale
Opaque.Icon {
source: gcd.assetPath + "core/favorite-24px.svg"
iconColor: Theme.toolbarIconColor
backgroundColor: rowColor
height: 18 * gcd.themeScale
width: 18 * gcd.themeScale
onClicked: { gcd.setPeerAuthorization(handle, Const.auth_approved)}
}
Opaque.Icon {
source: gcd.assetPath + "core/delete-24px.svg"
iconColor: Theme.toolbarIconColor
backgroundColor: rowColor
height: 18 * gcd.themeScale
width: 18 * gcd.themeScale
onClicked: { console.log("approve"); gcd.setPeerAuthorization(handle, Const.auth_blocked)}
}
}
onClicked: function(handle) { onClicked: function(handle) {
gcd.broadcast("ResetMessagePane") gcd.broadcast("ResetMessagePane")
isActive = true isActive = true
@ -65,7 +99,13 @@ Opaque.PortraitRow {
function setColors(status) { function setColors(status) {
//-2:WtfCodeError,-1:Error,0:Disconnected,1:Connecting,2:Connected,3:Authenticated,4:Synced,5:Failed,6:Killed //-2:WtfCodeError,-1:Error,0:Disconnected,1:Connecting,2:Connected,3:Authenticated,4:Synced,5:Failed,6:Killed
if (status == 4 || status == 3) {
if (authorization == Const.auth_blocked) {
portraitBorderColor = Theme.portraitBlockedBorderColor
portraitColor = Theme.portraitBlockedBackgroundColor
nameColor = Theme.portraitBlockedTextColor
onionColor = Theme.portraitBlockedTextColor
} else if (status == 4 || status == 3) {
portraitBorderColor = Theme.portraitOnlineBorderColor portraitBorderColor = Theme.portraitOnlineBorderColor
portraitColor = Theme.portraitOnlineBackgroundColor portraitColor = Theme.portraitOnlineBackgroundColor
nameColor = Theme.portraitOnlineTextColor nameColor = Theme.portraitOnlineTextColor

View File

@ -139,12 +139,11 @@ Item {
Connections { Connections {
target: gcd target: gcd
onUpdateMyProfile: function(_nick, _onion, _image, _tag) { onUpdateMyProfile: function(_nick, _onion, _image, _tag, _showBlocked) {
nick = _nick nick = _nick
onion = _onion onion = _onion
image = _image image = _image
tag = _tag tag = _tag
//realignProfile()
} }
onResetProfile: { realignProfile() } onResetProfile: { realignProfile() }

View File

@ -98,8 +98,8 @@ ColumnLayout {
handle: _handle handle: _handle
displayName: _displayName displayName: _displayName
image: _image image: _image
blocked: false
tag: _tag tag: _tag
Layout.fillWidth: true
} }
} }

View File

@ -190,5 +190,4 @@ Rectangle {
changeStatus() changeStatus()
} }
} }
} }