migrate to new cwtch authorizations + add new peer and blocked peer workflows to contact list #308
|
@ -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
7
go.mod
|
@ -3,12 +3,13 @@ module cwtch.im/ui
|
|||
go 1.12
|
||||
|
||||
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/log v1.0.0
|
||||
git.openprivacy.ca/openprivacy/log v1.0.1
|
||||
github.com/gopherjs/gopherjs v0.0.0-20200209183636-89e6cbcd0b6d // indirect
|
||||
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.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
6
go.sum
|
@ -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.11 h1:2+W2w9HDQowKwEGx4oRLywmn0NzQ0Sg9JEyBdR/V1mA=
|
||||
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/go.mod h1:HzezugpEx+nZ3LdyDsl0w6n45IJYnOt8uqldkLWmaqs=
|
||||
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/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.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/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
|
||||
github.com/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
|
||||
|
|
|
@ -5,6 +5,7 @@ const SchemaVersion = "schemaVersion"
|
|||
const Name = "name"
|
||||
const LastRead = "last-read"
|
||||
const Picture = "picture"
|
||||
const ShowBlocked = "show-blocked"
|
||||
|
||||
const ProfileTypeV1DefaultPassword = "v1-defaultPassword"
|
||||
const ProfileTypeV1Password = "v1-userPassword"
|
||||
|
|
|
@ -3,6 +3,7 @@ package handlers
|
|||
import (
|
||||
"cwtch.im/cwtch/app"
|
||||
"cwtch.im/cwtch/event"
|
||||
"cwtch.im/cwtch/model"
|
||||
"cwtch.im/cwtch/model/attr"
|
||||
peerC "cwtch.im/cwtch/peer"
|
||||
"cwtch.im/cwtch/protocol/connections"
|
||||
|
@ -77,13 +78,12 @@ func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) {
|
|||
case event.PeerStateChange:
|
||||
cxnState := connections.ConnectionStateToType[e.Data[event.ConnectionState]]
|
||||
|
||||
// if it's not in the.PeerHandler it's new. Only add once Authed
|
||||
if contact := peer.GetContact(e.Data[event.RemotePeer]); contact == nil {
|
||||
// Contact does not exist, we will add them but we won't know who they are until they are authenticated
|
||||
// So if we get any other state from an unknown contact we do nothing
|
||||
// (the next exists check will fail)
|
||||
if cxnState == connections.AUTHENTICATED {
|
||||
peer.AddContact(e.Data[event.RemotePeer], e.Data[event.RemotePeer], false)
|
||||
// New connection established
|
||||
if cxnState == connections.AUTHENTICATED {
|
||||
// if it's not in the peer it's new
|
||||
if contact := peer.GetContact(e.Data[event.RemotePeer]); contact == nil {
|
||||
// Contact does not exist, we will add them
|
||||
peer.AddContact(e.Data[event.RemotePeer], e.Data[event.RemotePeer], model.AuthUnknown)
|
||||
uiManager.AddContact(e.Data[event.RemotePeer])
|
||||
}
|
||||
}
|
||||
|
|
66
go/ui/gcd.go
66
go/ui/gcd.go
|
@ -3,6 +3,7 @@ package ui
|
|||
import (
|
||||
"cwtch.im/cwtch/app"
|
||||
"cwtch.im/cwtch/event"
|
||||
"cwtch.im/cwtch/model"
|
||||
"cwtch.im/cwtch/model/attr"
|
||||
"cwtch.im/cwtch/protocol/connections"
|
||||
"cwtch.im/ui/go/constants"
|
||||
|
@ -52,14 +53,13 @@ type GrandCentralDispatcher struct {
|
|||
_ func(failed bool) `signal:"ChangePasswordResponse"`
|
||||
|
||||
// contact list stuff
|
||||
_ func(handle, displayName, image string, badge, status int, blocked bool, loading bool, lastMsgTime int) `signal:"AddContact"`
|
||||
_ func(handle, displayName string) `signal:"UpdateContactDisplayName"`
|
||||
_ func(handle, image string) `signal:"UpdateContactPicture"`
|
||||
_ func(handle string, status int, loading bool) `signal:"UpdateContactStatus"`
|
||||
_ func(handle string, blocked bool) `signal:"UpdateContactBlocked"`
|
||||
_ func(handle string) `signal:"IncContactUnreadCount"`
|
||||
_ func(handle string) `signal:"RemoveContact"`
|
||||
_ func(handle, key, value string) `signal:"UpdateContactAttribute"`
|
||||
_ func(handle, displayName, image string, badge, status int, authorization string, loading bool, lastMsgTime int) `signal:"AddContact"`
|
||||
_ func(handle, displayName string) `signal:"UpdateContactDisplayName"`
|
||||
_ func(handle, image string) `signal:"UpdateContactPicture"`
|
||||
_ func(handle string, status int, loading bool) `signal:"UpdateContactStatus"`
|
||||
_ func(handle string) `signal:"IncContactUnreadCount"`
|
||||
_ func(handle string) `signal:"RemoveContact"`
|
||||
_ func(handle, key, value string) `signal:"UpdateContactAttribute"`
|
||||
|
||||
// messages pane stuff
|
||||
_ 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"`
|
||||
|
||||
// profile-area stuff
|
||||
_ func(name, onion, image, tag string) `signal:"UpdateMyProfile"`
|
||||
_ func(status int) `signal:"TorStatus"`
|
||||
_ func(name, onion, image, tag, showBlocked string) `signal:"UpdateMyProfile"`
|
||||
_ func(status int) `signal:"TorStatus"`
|
||||
|
||||
// settings helpers
|
||||
_ func(str string) `signal:"InvokePopup"`
|
||||
_ func(locale string, zoom float32, theme string) `signal:"SupplySettings"`
|
||||
_ 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)
|
||||
// ui
|
||||
|
@ -92,10 +92,10 @@ type GrandCentralDispatcher struct {
|
|||
_ func() `signal:"reloadProfileList,auto"`
|
||||
_ func(onion string) `signal:"deleteProfile,auto"`
|
||||
_ func(onion, currentPassword, newPassword string, defaultPass bool) `signal:"changePassword,auto""`
|
||||
_ func(key, val string) `signal:"storeSetting,auto"`
|
||||
// operating a profile
|
||||
_ func(message string, mid string) `signal:"sendMessage,auto"`
|
||||
_ func(onion string) `signal:"blockPeer,auto"`
|
||||
_ func(onion string) `signal:"unblockPeer,auto"`
|
||||
_ func(onion string, auth string) `signal:"setPeerAuthorization,auto"`
|
||||
_ func(onion string) `signal:"loadMessagesPane,auto"`
|
||||
_ func(signal string) `signal:"broadcast,auto"` // convenience relay signal
|
||||
_ func(str string) `signal:"importString,auto"`
|
||||
|
@ -339,7 +339,7 @@ func (this *GrandCentralDispatcher) requestPeerSettings() {
|
|||
contact := the.Peer.GetContact(this.SelectedConversation())
|
||||
if contact == nil {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -348,7 +348,7 @@ func (this *GrandCentralDispatcher) requestPeerSettings() {
|
|||
// Todo: Move to profile settings
|
||||
//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) {
|
||||
|
@ -397,7 +397,7 @@ func (this *GrandCentralDispatcher) createContact(onion string) {
|
|||
if contact := the.Peer.GetContact(onion); contact != nil {
|
||||
return
|
||||
}
|
||||
the.Peer.AddContact(onion, onion, false)
|
||||
the.Peer.AddContact(onion, onion, model.AuthApproved)
|
||||
the.Peer.PeerWithOnion(onion)
|
||||
}
|
||||
|
||||
|
@ -460,7 +460,7 @@ func (this *GrandCentralDispatcher) importString(str string) {
|
|||
this.InvokePopup("already have this contact")
|
||||
return //TODO: bring them to the duplicate
|
||||
} else {
|
||||
the.Peer.AddContact(name, onion, false)
|
||||
the.Peer.AddContact(name, onion, model.AuthApproved)
|
||||
the.Peer.PeerWithOnion(onion)
|
||||
}
|
||||
|
||||
|
@ -496,21 +496,18 @@ func (this *GrandCentralDispatcher) createGroup(server, groupName string) {
|
|||
the.Peer.JoinServer(server)
|
||||
}
|
||||
|
||||
func (this *GrandCentralDispatcher) blockPeer(onion string) {
|
||||
err := the.Peer.BlockPeer(onion)
|
||||
func (this *GrandCentralDispatcher) setPeerAuthorization(onion string, authorization string) {
|
||||
log.Debugf("Setting peer auth level to %v for %v\n", authorization, onion)
|
||||
err := the.Peer.SetContactAuthorization(onion, model.Authorization(authorization))
|
||||
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)
|
||||
}
|
||||
|
||||
func (this *GrandCentralDispatcher) unblockPeer(onion string) {
|
||||
err := the.Peer.UnblockPeer(onion)
|
||||
if err != nil {
|
||||
this.InvokePopup("Error Unblocking Peer: " + err.Error())
|
||||
this.RemoveContact(onion)
|
||||
this.GetUiManager(this.selectedProfile()).AddContact(onion)
|
||||
if model.Authorization(authorization) == model.AuthApproved {
|
||||
the.Peer.PeerWithOnion(onion)
|
||||
}
|
||||
the.Peer.PeerWithOnion(onion)
|
||||
this.UpdateContactBlocked(onion, false)
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
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()
|
||||
for i := range contacts {
|
||||
|
@ -658,6 +660,10 @@ func (this *GrandCentralDispatcher) changePassword(onion, currentPassword, newPa
|
|||
the.CwtchApp.ChangePeerPassword(onion, currentPassword, newPassword)
|
||||
}
|
||||
|
||||
func (this *GrandCentralDispatcher) storeSetting(key, val string) {
|
||||
the.Peer.SetAttribute(attr.GetSettingsScope(key), val)
|
||||
}
|
||||
|
||||
func (this *GrandCentralDispatcher) reloadProfileList() {
|
||||
this.ResetProfileList()
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ func getProfilePic(id string) string {
|
|||
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)
|
||||
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
|
||||
} else if !isPeer(handle) {
|
||||
|
@ -256,7 +256,7 @@ func (this *manager) AddContact(handle string) {
|
|||
unread := countUnread(contact.Timeline.GetMessages(), lastRead)
|
||||
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))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"cwtch.im/cwtch/storage/v1"
|
||||
"cwtch.im/ui/go/the"
|
||||
"encoding/json"
|
||||
"git.openprivacy.ca/openprivacy/log"
|
||||
"github.com/therecipe/qt/core"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
"golang.org/x/crypto/sha3"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
@ -31,34 +27,12 @@ var DefaultGlobalSettings = GlobalSettings{
|
|||
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 {
|
||||
var key [32]byte
|
||||
salt, err := ioutil.ReadFile(path.Join(directory, saltFile))
|
||||
if err != nil {
|
||||
var newSalt [128]byte
|
||||
key, newSalt, err = createKeySalt(password)
|
||||
key, newSalt, err = v1.CreateKeySalt(password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -68,7 +42,7 @@ func InitGlobalSettingsFile(directory string, password string) error {
|
|||
return err
|
||||
}
|
||||
} else {
|
||||
key = createKey(password, salt)
|
||||
key = v1.CreateKey(password, salt)
|
||||
}
|
||||
|
||||
the.GlobalSettingsFile = v1.NewFileStore(directory, GlobalSettingsFilename, key)
|
||||
|
|
|
@ -55,11 +55,16 @@
|
|||
<context>
|
||||
<name>ContactList</name>
|
||||
<message>
|
||||
<location filename="../qml/widgets/ContactList.qml" line="41"/>
|
||||
<location filename="../qml/widgets/ContactList.qml" line="53"/>
|
||||
<source>paste-address-to-add-contact</source>
|
||||
<extracomment>ex: "... paste an address here to add a contact ..."</extracomment>
|
||||
<translation type="unfinished">Adresse hier hinzufügen, um einen Kontakt aufzunehmen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/ContactList.qml" line="251"/>
|
||||
<source>blocked</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>GroupSettingsPane</name>
|
||||
|
@ -227,38 +232,38 @@
|
|||
<context>
|
||||
<name>PeerSettingsPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="25"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="26"/>
|
||||
<source>address-label</source>
|
||||
<translation>Adresse</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="30"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="31"/>
|
||||
<source>copy-btn</source>
|
||||
<translation>Kopieren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="34"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="35"/>
|
||||
<source>copied-to-clipboard-notification</source>
|
||||
<extracomment>notification: copied to clipboard</extracomment>
|
||||
<translation>in die Zwischenablage kopiert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="46"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="47"/>
|
||||
<source>display-name-label</source>
|
||||
<translation>Angezeigter Name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="50"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="51"/>
|
||||
<source>save-btn</source>
|
||||
<translation>speichern</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="89"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="92"/>
|
||||
<source>delete-btn</source>
|
||||
<translation>löschen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="65"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="64"/>
|
||||
<source>block-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -371,7 +376,7 @@
|
|||
<context>
|
||||
<name>ProfileList</name>
|
||||
<message>
|
||||
<location filename="../qml/widgets/ProfileList.qml" line="108"/>
|
||||
<location filename="../qml/widgets/ProfileList.qml" line="107"/>
|
||||
<source>add-new-profile-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -447,34 +452,34 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="84"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="86"/>
|
||||
<source>large-text-label</source>
|
||||
<translation>Groß</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="92"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="94"/>
|
||||
<source>setting-theme</source>
|
||||
<extracomment>Theme</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="101"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="103"/>
|
||||
<source>theme-light</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="102"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="104"/>
|
||||
<source>theme-dark</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="151"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="153"/>
|
||||
<source>version %1</source>
|
||||
<extracomment>Version %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="160"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="162"/>
|
||||
<source>builddate %2</source>
|
||||
<extracomment>Built on: %2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
|
|
Binary file not shown.
|
@ -55,11 +55,16 @@
|
|||
<context>
|
||||
<name>ContactList</name>
|
||||
<message>
|
||||
<location filename="../qml/widgets/ContactList.qml" line="41"/>
|
||||
<location filename="../qml/widgets/ContactList.qml" line="53"/>
|
||||
<source>paste-address-to-add-contact</source>
|
||||
<extracomment>ex: "... paste an address here to add a contact ..."</extracomment>
|
||||
<translation>... paste an address here to add a contact...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/ContactList.qml" line="251"/>
|
||||
<source>blocked</source>
|
||||
<translation>Blocked</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EmojiDrawer</name>
|
||||
|
@ -322,33 +327,33 @@ Right-click to reset.</translation>
|
|||
<context>
|
||||
<name>PeerSettingsPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="25"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="26"/>
|
||||
<source>address-label</source>
|
||||
<translation>Address</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="30"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="31"/>
|
||||
<source>copy-btn</source>
|
||||
<translation>Copy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="34"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="35"/>
|
||||
<source>copied-to-clipboard-notification</source>
|
||||
<extracomment>notification: copied to clipboard</extracomment>
|
||||
<translation>Copied to Clipboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="46"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="47"/>
|
||||
<source>display-name-label</source>
|
||||
<translation>Display Name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="50"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="51"/>
|
||||
<source>save-btn</source>
|
||||
<translation>Save</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="65"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="64"/>
|
||||
<source>block-btn</source>
|
||||
<translation>Block Peer</translation>
|
||||
</message>
|
||||
|
@ -357,7 +362,7 @@ Right-click to reset.</translation>
|
|||
<translation type="vanished">Unblock Peer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="89"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="92"/>
|
||||
<source>delete-btn</source>
|
||||
<translation>Delete</translation>
|
||||
</message>
|
||||
|
@ -478,7 +483,7 @@ Right-click to reset.</translation>
|
|||
<context>
|
||||
<name>ProfileList</name>
|
||||
<message>
|
||||
<location filename="../qml/widgets/ProfileList.qml" line="108"/>
|
||||
<location filename="../qml/widgets/ProfileList.qml" line="107"/>
|
||||
<source>add-new-profile-btn</source>
|
||||
<translation>Add new profile</translation>
|
||||
</message>
|
||||
|
@ -563,34 +568,34 @@ Right-click to reset.</translation>
|
|||
<translation>Zoom level</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="84"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="86"/>
|
||||
<source>large-text-label</source>
|
||||
<translation>Large</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="92"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="94"/>
|
||||
<source>setting-theme</source>
|
||||
<extracomment>Theme</extracomment>
|
||||
<translation>Theme</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="101"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="103"/>
|
||||
<source>theme-light</source>
|
||||
<translation>Light</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="102"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="104"/>
|
||||
<source>theme-dark</source>
|
||||
<translation>Dark</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="151"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="153"/>
|
||||
<source>version %1</source>
|
||||
<extracomment>Version %1</extracomment>
|
||||
<translation>Version %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="160"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="162"/>
|
||||
<source>builddate %2</source>
|
||||
<extracomment>Built on: %2</extracomment>
|
||||
<translation>Built on: %2</translation>
|
||||
|
|
|
@ -55,11 +55,16 @@
|
|||
<context>
|
||||
<name>ContactList</name>
|
||||
<message>
|
||||
<location filename="../qml/widgets/ContactList.qml" line="41"/>
|
||||
<location filename="../qml/widgets/ContactList.qml" line="53"/>
|
||||
<source>paste-address-to-add-contact</source>
|
||||
<extracomment>ex: "... paste an address here to add a contact ..."</extracomment>
|
||||
<translation type="unfinished">... coller une adresse ici pour ajouter un contact...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/ContactList.qml" line="251"/>
|
||||
<source>blocked</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>GroupSettingsPane</name>
|
||||
|
@ -227,38 +232,38 @@
|
|||
<context>
|
||||
<name>PeerSettingsPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="25"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="26"/>
|
||||
<source>address-label</source>
|
||||
<translation>Adresse</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="30"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="31"/>
|
||||
<source>copy-btn</source>
|
||||
<translation>Copier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="34"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="35"/>
|
||||
<source>copied-to-clipboard-notification</source>
|
||||
<extracomment>notification: copied to clipboard</extracomment>
|
||||
<translation>Copié dans le presse-papier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="46"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="47"/>
|
||||
<source>display-name-label</source>
|
||||
<translation>Pseudo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="50"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="51"/>
|
||||
<source>save-btn</source>
|
||||
<translation>Sauvegarder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="89"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="92"/>
|
||||
<source>delete-btn</source>
|
||||
<translation>Effacer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="65"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="64"/>
|
||||
<source>block-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -371,7 +376,7 @@
|
|||
<context>
|
||||
<name>ProfileList</name>
|
||||
<message>
|
||||
<location filename="../qml/widgets/ProfileList.qml" line="108"/>
|
||||
<location filename="../qml/widgets/ProfileList.qml" line="107"/>
|
||||
<source>add-new-profile-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -447,34 +452,34 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="84"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="86"/>
|
||||
<source>large-text-label</source>
|
||||
<translation type="unfinished">Large</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="92"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="94"/>
|
||||
<source>setting-theme</source>
|
||||
<extracomment>Theme</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="101"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="103"/>
|
||||
<source>theme-light</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="102"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="104"/>
|
||||
<source>theme-dark</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="151"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="153"/>
|
||||
<source>version %1</source>
|
||||
<extracomment>Version %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="160"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="162"/>
|
||||
<source>builddate %2</source>
|
||||
<extracomment>Built on: %2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
|
|
|
@ -55,11 +55,16 @@
|
|||
<context>
|
||||
<name>ContactList</name>
|
||||
<message>
|
||||
<location filename="../qml/widgets/ContactList.qml" line="41"/>
|
||||
<location filename="../qml/widgets/ContactList.qml" line="53"/>
|
||||
<source>paste-address-to-add-contact</source>
|
||||
<extracomment>ex: "... paste an address here to add a contact ..."</extracomment>
|
||||
<translation type="unfinished">… cole um endereço aqui para adicionar um contato…</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/ContactList.qml" line="251"/>
|
||||
<source>blocked</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>GroupSettingsPane</name>
|
||||
|
@ -227,38 +232,38 @@
|
|||
<context>
|
||||
<name>PeerSettingsPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="25"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="26"/>
|
||||
<source>address-label</source>
|
||||
<translation>Endereço</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="30"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="31"/>
|
||||
<source>copy-btn</source>
|
||||
<translation>Copiar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="34"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="35"/>
|
||||
<source>copied-to-clipboard-notification</source>
|
||||
<extracomment>notification: copied to clipboard</extracomment>
|
||||
<translation>Copiado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="46"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="47"/>
|
||||
<source>display-name-label</source>
|
||||
<translation>Nome de Exibição</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="50"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="51"/>
|
||||
<source>save-btn</source>
|
||||
<translation>Salvar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="89"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="92"/>
|
||||
<source>delete-btn</source>
|
||||
<translation>Deletar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="65"/>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="64"/>
|
||||
<source>block-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -371,7 +376,7 @@
|
|||
<context>
|
||||
<name>ProfileList</name>
|
||||
<message>
|
||||
<location filename="../qml/widgets/ProfileList.qml" line="108"/>
|
||||
<location filename="../qml/widgets/ProfileList.qml" line="107"/>
|
||||
<source>add-new-profile-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -447,34 +452,34 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="84"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="86"/>
|
||||
<source>large-text-label</source>
|
||||
<translation>Grande</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="92"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="94"/>
|
||||
<source>setting-theme</source>
|
||||
<extracomment>Theme</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="101"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="103"/>
|
||||
<source>theme-light</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="102"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="104"/>
|
||||
<source>theme-dark</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="151"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="153"/>
|
||||
<source>version %1</source>
|
||||
<extracomment>Version %1</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="160"/>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="162"/>
|
||||
<source>builddate %2</source>
|
||||
<extracomment>Built on: %2</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
|
|
|
@ -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"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
singleton Const 1.0 Const.qml
|
|
@ -348,8 +348,6 @@ ApplicationWindow {
|
|||
if (Qt.application.state == 4) {
|
||||
// Active
|
||||
gcd.onActivate()
|
||||
console.log(Fonts.applicationFontRegular.name)
|
||||
console.log(Fonts.applicationFontBold.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 0ec6a2df571e1a9c462d902cfc89f2402a9bef97
|
||||
Subproject commit 0505934172c42fc589f8c0e095e1e8f0efeda245
|
|
@ -10,12 +10,13 @@ import QtQuick.Controls.Styles 1.4
|
|||
import "../opaque" as Opaque
|
||||
import "../opaque/styles"
|
||||
import "../opaque/theme"
|
||||
import "../const"
|
||||
|
||||
Opaque.SettingsList { // settingsPane
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
|
||||
property bool blocked
|
||||
property string authorization
|
||||
|
||||
settings: Column {
|
||||
anchors.fill: parent
|
||||
|
@ -59,8 +60,6 @@ Opaque.SettingsList { // settingsPane
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Opaque.Setting {
|
||||
label: qsTr("block-btn")
|
||||
|
||||
|
@ -68,15 +67,19 @@ Opaque.SettingsList { // settingsPane
|
|||
field: Opaque.ToggleSwitch {
|
||||
anchors.right: parent.right
|
||||
|
||||
isToggled: root.blocked // ? qsTr("unblock-btn") : qsTr("block-btn")
|
||||
isToggled: root.authorization == Const.auth_blocked
|
||||
onToggled: function() {
|
||||
if (root.blocked) {
|
||||
gcd.unblockPeer(txtOnion.text)
|
||||
console.log("peer block toddle for " + txtOnion.text + " currently: " + root.authorization)
|
||||
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 {
|
||||
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.blocked
|
||||
isToggled = root.authorization == Const.auth_blocked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,10 +106,10 @@ Opaque.SettingsList { // settingsPane
|
|||
Connections {
|
||||
target: gcd
|
||||
|
||||
onSupplyPeerSettings: function(onion, nick, blocked) {
|
||||
onSupplyPeerSettings: function(onion, nick, authorization) {
|
||||
txtOnion.text = onion
|
||||
txtDisplayName.text = nick
|
||||
root.blocked = blocked
|
||||
root.authorization = authorization
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ Opaque.SettingsList { // settingsPane
|
|||
value: gcd.themeScale
|
||||
live: false
|
||||
stepSize: 0.1
|
||||
|
||||
onValueChanged: {
|
||||
gcd.themeScale = zoomSlider.value
|
||||
}
|
||||
|
@ -88,7 +89,6 @@ Opaque.SettingsList { // settingsPane
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
Opaque.Setting {
|
||||
//: Theme
|
||||
label: qsTr("setting-theme")
|
||||
|
@ -193,10 +193,6 @@ text: qsTr("block-unknown-label")
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -6,11 +6,13 @@ import QtQuick.Layouts 1.3
|
|||
|
||||
import "../opaque" as Opaque
|
||||
import "../opaque/theme"
|
||||
import "../const"
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
property alias dualPane: myprof.dualPane
|
||||
property real logscale: 4 * Math.log10(gcd.themeScale + 1)
|
||||
|
||||
spacing: 10
|
||||
|
||||
|
@ -26,6 +28,16 @@ ColumnLayout {
|
|||
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 {
|
||||
id: searchAddText
|
||||
|
@ -61,10 +73,9 @@ ColumnLayout {
|
|||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: parent.width
|
||||
Layout.maximumWidth: parent.width
|
||||
contentWidth: colContacts.width
|
||||
contentWidth: parent.width
|
||||
contentHeight: colContacts.height
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
maximumFlickVelocity: 400
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
policy: ScrollBar.AsNeeded
|
||||
|
@ -80,6 +91,8 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ColumnLayout {
|
||||
id: colContacts
|
||||
width: root.width
|
||||
|
@ -88,17 +101,29 @@ ColumnLayout {
|
|||
Connections { // ADD/REMOVE CONTACT ENTRIES
|
||||
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++) {
|
||||
if (contactsModel.get(i)["_handle"] == handle) {
|
||||
for (var i = 0; i < model.count; i++) {
|
||||
if (model.get(i)["_handle"] == handle) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var index = contactsModel.count
|
||||
for (var i = 0; i < contactsModel.count; i++) {
|
||||
if (contactsModel.get(i)["_lastMsgTs"] < lastMsgTs) {
|
||||
// Sort order: [unknown,authed][most recent message]
|
||||
var index = model.count
|
||||
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
|
||||
break
|
||||
}
|
||||
|
@ -106,26 +131,23 @@ ColumnLayout {
|
|||
|
||||
var newContact = {
|
||||
"_handle": handle,
|
||||
"_displayName": displayName + (blocked ? " (blocked)" : "" ),
|
||||
"_displayName": displayName,
|
||||
"_image": image,
|
||||
"_badge": badge,
|
||||
"_status": status,
|
||||
"_blocked": blocked,
|
||||
"_authorization": authorization,
|
||||
"_loading": loading,
|
||||
"_loading": loading,
|
||||
"_lastMsgTs": lastMsgTs
|
||||
}
|
||||
|
||||
contactsModel.insert(index, newContact)
|
||||
model.insert(index, newContact)
|
||||
}
|
||||
|
||||
onRemoveContact: function(handle) {
|
||||
for(var i = 0; i < contactsModel.count; i++){
|
||||
if(contactsModel.get(i)["_handle"] == handle) {
|
||||
console.log("deleting contact " + contactsModel.get(i)["_handle"])
|
||||
contactsModel.remove(i)
|
||||
return
|
||||
}
|
||||
var removed = root.removeContact(contactsModel, handle)
|
||||
if (!removed) {
|
||||
root.removeContact(blockedContactsModel, handle)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,6 +164,7 @@ ColumnLayout {
|
|||
|
||||
onResetProfile: function() {
|
||||
contactsModel.clear()
|
||||
blockedContactsModel.clear()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,6 +173,7 @@ ColumnLayout {
|
|||
}
|
||||
|
||||
Repeater {
|
||||
id: contactRepeater
|
||||
model: contactsModel // ... AND DISPLAYED HERE
|
||||
delegate: ContactRow {
|
||||
handle: _handle
|
||||
|
@ -157,17 +181,122 @@ ColumnLayout {
|
|||
image: _image
|
||||
badge: _badge
|
||||
status: _status
|
||||
blocked: _blocked
|
||||
authorization: _authorization
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -10,11 +10,16 @@ import QtQuick.Controls.Styles 1.4
|
|||
import "../opaque" as Opaque
|
||||
import "../opaque/styles"
|
||||
import "../opaque/theme"
|
||||
import "../const"
|
||||
|
||||
Opaque.PortraitRow {
|
||||
property int status: 0
|
||||
property int badge
|
||||
property bool loading
|
||||
property string authorization
|
||||
|
||||
// TODO: should be in ContactRow
|
||||
property bool blocked
|
||||
|
||||
badgeColor: Theme.portraitContactBadgeColor
|
||||
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) {
|
||||
gcd.broadcast("ResetMessagePane")
|
||||
isActive = true
|
||||
|
@ -65,7 +99,13 @@ Opaque.PortraitRow {
|
|||
|
||||
function setColors(status) {
|
||||
//-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
|
||||
portraitColor = Theme.portraitOnlineBackgroundColor
|
||||
nameColor = Theme.portraitOnlineTextColor
|
||||
|
|
|
@ -139,12 +139,11 @@ Item {
|
|||
Connections {
|
||||
target: gcd
|
||||
|
||||
onUpdateMyProfile: function(_nick, _onion, _image, _tag) {
|
||||
onUpdateMyProfile: function(_nick, _onion, _image, _tag, _showBlocked) {
|
||||
nick = _nick
|
||||
onion = _onion
|
||||
image = _image
|
||||
tag = _tag
|
||||
//realignProfile()
|
||||
}
|
||||
|
||||
onResetProfile: { realignProfile() }
|
||||
|
|
|
@ -98,8 +98,8 @@ ColumnLayout {
|
|||
handle: _handle
|
||||
displayName: _displayName
|
||||
image: _image
|
||||
blocked: false
|
||||
tag: _tag
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -190,5 +190,4 @@ Rectangle {
|
|||
changeStatus()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Reference in New Issue