forked from cwtch.im/ui
Compare commits
19 Commits
cwtch-alph
...
master
Author | SHA1 | Date |
---|---|---|
erinn | a43d148da8 | |
Dan Ballard | e4db07bee8 | |
erinn | c36d74639e | |
Dan Ballard | 901109409b | |
erinn | 7a9022bac1 | |
Sarah Jamie Lewis | bcd81c813d | |
erinn | ac6fb8d2e8 | |
Sarah Jamie Lewis | c483bded55 | |
erinn | 713c3ed72d | |
Sarah Jamie Lewis | 153651478a | |
Sarah Jamie Lewis | eaa700ba57 | |
erinn | c4b0eeccfb | |
erinn | 202153bab2 | |
Sarah Jamie Lewis | d4abc25ed0 | |
erinn | ebdaf54ff9 | |
Dan Ballard | 2e7f49bde4 | |
Sarah Jamie Lewis | a9b1f7904a | |
Dan Ballard | d6fc4766a0 | |
Dan Ballard | 3cc713ed9a |
19
.drone.yml
19
.drone.yml
|
@ -7,9 +7,9 @@ pipeline:
|
|||
mem_limit: 3G
|
||||
image: therecipe/qt:linux
|
||||
when:
|
||||
branch: master
|
||||
repo: cwtch.im/ui
|
||||
branch: master
|
||||
event: [ push, pull_request ]
|
||||
status: [ success ]
|
||||
environment:
|
||||
- QT_DIR=/opt/Qt
|
||||
- QT_DOCKER='true'
|
||||
|
@ -30,9 +30,9 @@ pipeline:
|
|||
mem_limit: 3G
|
||||
image: therecipe/qt:android
|
||||
when:
|
||||
branch: master
|
||||
repo: cwtch.im/ui
|
||||
branch: master
|
||||
event: push
|
||||
status: [ success ]
|
||||
environment:
|
||||
- QT_DIR=/opt/Qt
|
||||
- QT_DOCKER='true'
|
||||
|
@ -55,9 +55,9 @@ pipeline:
|
|||
mem_limit: 3G
|
||||
image: therecipe/qt:windows_64_shared
|
||||
when:
|
||||
branch: master
|
||||
repo: cwtch.im/ui
|
||||
branch: master
|
||||
event: push
|
||||
status: [ success ]
|
||||
environment:
|
||||
- QT_DIR=/opt/Qt
|
||||
- QT_DOCKER='true'
|
||||
|
@ -83,7 +83,8 @@ pipeline:
|
|||
image: pivotaldata/concourse-ssh
|
||||
secrets: [buildfiles_key]
|
||||
when:
|
||||
branch: master
|
||||
repo: cwtch.im/ui
|
||||
branch: master
|
||||
event: push
|
||||
status: [ success ]
|
||||
commands:
|
||||
|
@ -103,10 +104,14 @@ pipeline:
|
|||
skip_verify: true
|
||||
from: drone@openprivacy.ca
|
||||
when:
|
||||
repo: cwtch.im/ui
|
||||
branch: master
|
||||
status: [ failure ]
|
||||
notify-gogs:
|
||||
image: openpriv/drone-gogs
|
||||
when:
|
||||
repo: cwtch.im/ui
|
||||
branch: master
|
||||
event: pull_request
|
||||
status: [ success, changed, failure ]
|
||||
secrets: [gogs_account_token]
|
||||
|
|
|
@ -5,3 +5,4 @@ rcc*
|
|||
*.qmlc
|
||||
*.jsc
|
||||
vendor/
|
||||
.directory
|
||||
|
|
|
@ -41,3 +41,9 @@ We supply an arm-pie version of tor in `android/libs/armeabi-v7a` with the name
|
|||
If all that is done, then check out cwtch.im/ui and run `qtdeploy` in the root of it.
|
||||
|
||||
Currently you will need to manually run tor first before running cwtch.im/ui. Use the included tor and torrc file: `tor -f torrc`
|
||||
|
||||
# Development
|
||||
|
||||
## Translations
|
||||
|
||||
Translations can be update by runing QT Linguist in the project directory (`linguist`) and loading and editing any of the `i18n/translate_*.ts` files. To add a new translation, please register the file in qml.qrc. To update translations, run `lupdate ui.pro` to update the editable .ts files and when you are done run `lrelease ui.pro` to generate the .qm files that are used at runtime.
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func IncomingListener(callback func(*gobjects.Message), groupErrorCallback func(string,string)) {
|
||||
func IncomingListener(callback func(*gobjects.Message), groupErrorCallback func(string, string,string)) {
|
||||
q := event.NewEventQueue(1000)
|
||||
the.CwtchApp.EventBus().Subscribe(event.NewMessageFromPeer, q.EventChannel)
|
||||
the.CwtchApp.EventBus().Subscribe(event.NewMessageFromGroup, q.EventChannel)
|
||||
|
@ -68,9 +68,9 @@ func IncomingListener(callback func(*gobjects.Message), groupErrorCallback func(
|
|||
case event.NewGroupInvite:
|
||||
log.Debugf("got a group invite!")
|
||||
case event.SendMessageToGroupError:
|
||||
groupErrorCallback(e.Data[event.Signature], e.Data[event.Error])
|
||||
groupErrorCallback(e.Data[event.GroupServer], e.Data[event.Signature], e.Data[event.Error])
|
||||
case event.SendMessageToPeerError:
|
||||
groupErrorCallback(e.Data[event.Signature], e.Data[event.Error])
|
||||
groupErrorCallback(e.Data[event.RemotePeer], e.Data[event.Signature], e.Data[event.Error])
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,6 @@ func RandomProfileImage(onion string) string {
|
|||
barr, err := base32.StdEncoding.DecodeString(strings.ToUpper(onion))
|
||||
if err != nil || len(barr) != 35 {
|
||||
log.Errorf("error: %v %v %v\n", onion, err, barr)
|
||||
panic("lol")
|
||||
return "qrc:/qml/images/extra/openprivacy.png"
|
||||
}
|
||||
return "qrc:/qml/images/profiles/" + choices[int(barr[33])%len(choices)] + ".png"
|
||||
|
|
|
@ -12,4 +12,5 @@ type Message struct {
|
|||
MessageID string
|
||||
Timestamp time.Time
|
||||
Acknowledged bool
|
||||
Error bool
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ type GrandCentralDispatcher struct {
|
|||
_ 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) `signal:"AppendMessage"`
|
||||
_ func(handle, from, displayName, message, image string, mID string, fromMe bool, ts string, ackd bool, error bool) `signal:"AppendMessage"`
|
||||
_ func() `signal:"ClearMessages"`
|
||||
_ func() `signal:"ResetMessagePane"`
|
||||
_ func(mID string) `signal:"Acknowledged"`
|
||||
|
@ -99,6 +99,7 @@ func (this *GrandCentralDispatcher) sendMessage(message string, mID string) {
|
|||
mID,
|
||||
time.Now(),
|
||||
false,
|
||||
false,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
@ -118,7 +119,7 @@ func (this *GrandCentralDispatcher) sendMessage(message string, mID string) {
|
|||
mID = the.Peer.SendMessageToPeer(to, message)
|
||||
|
||||
this.UIState.AddMessage(&gobjects.Message{
|
||||
this.CurrentOpenConversation(),
|
||||
to,
|
||||
"me",
|
||||
"",
|
||||
message,
|
||||
|
@ -127,6 +128,7 @@ func (this *GrandCentralDispatcher) sendMessage(message string, mID string) {
|
|||
mID,
|
||||
time.Now(),
|
||||
false,
|
||||
false,
|
||||
})
|
||||
|
||||
ackID := new(the.AckId)
|
||||
|
@ -201,7 +203,8 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) {
|
|||
tl[i].PeerID == the.Peer.GetProfile().Onion,
|
||||
tl[i].Timestamp.Format(constants.TIME_FORMAT),
|
||||
tl[i].Received.Equal(time.Unix(0,0)) == false, // If the received timestamp is epoch, we have not yet received this message through an active server
|
||||
)
|
||||
false,
|
||||
)
|
||||
}
|
||||
return
|
||||
} // ELSE LOAD CONTACT
|
||||
|
@ -222,6 +225,7 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) {
|
|||
if messages[i].FromMe {
|
||||
from = "me"
|
||||
}
|
||||
|
||||
this.AppendMessage(
|
||||
messages[i].Handle,
|
||||
from,
|
||||
|
@ -231,10 +235,11 @@ func (this *GrandCentralDispatcher) loadMessagesPaneHelper(handle string) {
|
|||
messages[i].MessageID,
|
||||
messages[i].FromMe,
|
||||
messages[i].Timestamp.Format(constants.TIME_FORMAT),
|
||||
true,
|
||||
false,
|
||||
messages[i].Error,
|
||||
)
|
||||
for _,id := range the.AcknowledgementIDs[messages[i].Handle] {
|
||||
if id.ID == messages[i].MessageID && id.Ack{
|
||||
if id.ID == messages[i].MessageID && id.Ack && !id.Error {
|
||||
this.Acknowledged(id.ID)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,16 +9,18 @@ import (
|
|||
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type InterfaceState struct {
|
||||
parentGcd *GrandCentralDispatcher
|
||||
contacts map[string]*gobjects.Contact
|
||||
messages map[string][]*gobjects.Message
|
||||
messages sync.Map
|
||||
}
|
||||
|
||||
func NewUIState(gcd *GrandCentralDispatcher) (uis InterfaceState) {
|
||||
uis = InterfaceState{gcd, make(map[string]*gobjects.Contact), make(map[string][]*gobjects.Message)}
|
||||
uis = InterfaceState{gcd, make(map[string]*gobjects.Contact), sync.Map{}}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -86,16 +88,33 @@ func (this *InterfaceState) GetContact(handle string) *gobjects.Contact {
|
|||
return this.contacts[handle]
|
||||
}
|
||||
|
||||
func (this *InterfaceState) AddGroupError(signature string, err string) {
|
||||
func (this *InterfaceState) AddSendMessageError(peer string, signature string, err string) {
|
||||
acklist := the.AcknowledgementIDs[peer]
|
||||
for _,ack := range acklist {
|
||||
if ack.ID == signature {
|
||||
ack.Error = true
|
||||
}
|
||||
}
|
||||
messages,_ := this.messages.Load(peer)
|
||||
messageList,_ := messages.([]*gobjects.Message)
|
||||
|
||||
for _,message := range messageList {
|
||||
if message.MessageID == signature {
|
||||
message.Error = true
|
||||
}
|
||||
}
|
||||
log.Debugf("Received Error Sending Message: %v %v", signature, err)
|
||||
// FIXME: Sometimes, for the first Peer message we send our error beats our message to the UI
|
||||
time.Sleep(time.Second*1)
|
||||
this.parentGcd.GroupSendError(signature, err)
|
||||
}
|
||||
|
||||
func (this *InterfaceState) AddMessage(m *gobjects.Message) {
|
||||
this.GetContact(m.From)
|
||||
|
||||
_, found := this.messages[m.Handle]
|
||||
_,found := this.messages.Load(m.Handle)
|
||||
if !found {
|
||||
this.messages[m.Handle] = make([]*gobjects.Message, 0)
|
||||
this.messages.Store(m.Handle, make([]*gobjects.Message, 0))
|
||||
}
|
||||
|
||||
// Ack message sent to group
|
||||
|
@ -107,17 +126,22 @@ func (this *InterfaceState) AddMessage(m *gobjects.Message) {
|
|||
// If an ack, swallow the message and ack from the list.
|
||||
acklist := the.AcknowledgementIDs[m.From]
|
||||
for _,ack := range acklist {
|
||||
ack.Ack = true
|
||||
this.parentGcd.Acknowledged(ack.ID)
|
||||
if ack.Error == false {
|
||||
ack.Ack = true
|
||||
this.parentGcd.Acknowledged(ack.ID)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.messages[m.Handle] = append(this.messages[m.Handle], m)
|
||||
|
||||
messages,_ := this.messages.Load(m.Handle)
|
||||
messageList,_ := messages.([]*gobjects.Message)
|
||||
this.messages.Store(m.Handle, append(messageList, m))
|
||||
|
||||
// If we have this group loaded already
|
||||
if this.parentGcd.CurrentOpenConversation() == m.Handle {
|
||||
// If the message is not from the user then add it, otherwise, just acknowledge.
|
||||
if !m.FromMe || !m.Acknowledged {
|
||||
this.parentGcd.AppendMessage(m.Handle, m.From, m.DisplayName, m.Message, m.Image, m.MessageID, m.FromMe, m.Timestamp.Format(constants.TIME_FORMAT), m.Acknowledged)
|
||||
this.parentGcd.AppendMessage(m.Handle, m.From, m.DisplayName, m.Message, m.Image, m.MessageID, m.FromMe, m.Timestamp.Format(constants.TIME_FORMAT), m.Acknowledged, m.Error)
|
||||
} else {
|
||||
this.parentGcd.Acknowledged(m.MessageID)
|
||||
}
|
||||
|
@ -133,11 +157,13 @@ func (this *InterfaceState) AddMessage(m *gobjects.Message) {
|
|||
}
|
||||
|
||||
func (this *InterfaceState) GetMessages(handle string) []*gobjects.Message {
|
||||
_, found := this.messages[handle]
|
||||
_,found := this.messages.Load(handle)
|
||||
if !found {
|
||||
this.messages[handle] = make([]*gobjects.Message, 0)
|
||||
this.messages.Store(handle, make([]*gobjects.Message, 0))
|
||||
}
|
||||
return this.messages[handle]
|
||||
messages,found := this.messages.Load(handle)
|
||||
messageList,_ := messages.([]*gobjects.Message)
|
||||
return messageList
|
||||
}
|
||||
|
||||
func (this *InterfaceState) UpdateContact(handle string) {
|
||||
|
|
|
@ -12,6 +12,7 @@ var CwtchDir string
|
|||
type AckId struct {
|
||||
ID string
|
||||
Ack bool
|
||||
Error bool
|
||||
}
|
||||
|
||||
var AcknowledgementIDs map[string][]*AckId
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,289 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="de_DE">
|
||||
<context>
|
||||
<name>AddGroupPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/AddGroupPane.qml" line="17"/>
|
||||
<source>create-group-title</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/AddGroupPane.qml" line="27"/>
|
||||
<source>server-label</source>
|
||||
<extracomment>Server label</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/AddGroupPane.qml" line="38"/>
|
||||
<source>group-name-label</source>
|
||||
<extracomment>Group name label</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/AddGroupPane.qml" line="45"/>
|
||||
<source>default-group-name</source>
|
||||
<extracomment>default suggested group name</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/AddGroupPane.qml" line="50"/>
|
||||
<source>create-group-btn</source>
|
||||
<extracomment>create group button</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BulletinOverlay</name>
|
||||
<message>
|
||||
<location filename="../qml/overlays/BulletinOverlay.qml" line="181"/>
|
||||
<source>new-bulletin-label</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/overlays/BulletinOverlay.qml" line="193"/>
|
||||
<source>post-new-bulletin-label</source>
|
||||
<extracomment>Post a new Bulletin Post</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/overlays/BulletinOverlay.qml" line="199"/>
|
||||
<source>title-placeholder</source>
|
||||
<extracomment>title place holder text</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>GroupSettingsPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="30"/>
|
||||
<source>server-label</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="41"/>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="62"/>
|
||||
<source>copy-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="51"/>
|
||||
<source>invitation-label</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="72"/>
|
||||
<source>group-name-label</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="81"/>
|
||||
<source>save-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="91"/>
|
||||
<source>invite-to-group-label</source>
|
||||
<extracomment>Invite someone to the group</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="102"/>
|
||||
<source>invite-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="111"/>
|
||||
<source>delete-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ListOverlay</name>
|
||||
<message>
|
||||
<location filename="../qml/overlays/ListOverlay.qml" line="162"/>
|
||||
<source>add-list-item</source>
|
||||
<extracomment>Add a New List Item</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/overlays/ListOverlay.qml" line="174"/>
|
||||
<source>add-new-item</source>
|
||||
<extracomment>Add a new item to the list</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/overlays/ListOverlay.qml" line="180"/>
|
||||
<source>todo-placeholder</source>
|
||||
<extracomment>Todo... placeholder text</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MembershipOverlay</name>
|
||||
<message>
|
||||
<location filename="../qml/overlays/MembershipOverlay.qml" line="21"/>
|
||||
<source>membership-description</source>
|
||||
<extracomment>Below is a list of users who have sent messages to the group. This list may not reflect all users who have access to the group.</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Message</name>
|
||||
<message>
|
||||
<location filename="../qml/widgets/Message.qml" line="55"/>
|
||||
<source>dm-tooltip</source>
|
||||
<extracomment>Click to DM</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/Message.qml" line="154"/>
|
||||
<source>could-not-send-msg-error</source>
|
||||
<extracomment>Could not send this message</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/Message.qml" line="154"/>
|
||||
<source>acknowledged-label</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/Message.qml" line="154"/>
|
||||
<source>pending-label</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MyProfile</name>
|
||||
<message>
|
||||
<location filename="../qml/widgets/MyProfile.qml" line="169"/>
|
||||
<source>copy-btn</source>
|
||||
<extracomment>Button for copying profile onion address to clipboard</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/MyProfile.qml" line="173"/>
|
||||
<source>copied-clipboard-notification</source>
|
||||
<extracomment>Copied to clipboard</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/MyProfile.qml" line="203"/>
|
||||
<source>new-group-btn</source>
|
||||
<extracomment>create new group button</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/MyProfile.qml" line="213"/>
|
||||
<source>paste-address-to-add-contact</source>
|
||||
<extracomment>ex: "... paste an address here to add a contact ..."</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OverlayPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="44"/>
|
||||
<source>accept-group-invite-label</source>
|
||||
<extracomment>Do you want to accept the invitation to $GROUP</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="49"/>
|
||||
<source>accept-group-btn</source>
|
||||
<extracomment>Accept group invite button</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="59"/>
|
||||
<source>reject-group-btn</source>
|
||||
<extracomment>Reject Group invite button</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="73"/>
|
||||
<source>chat-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="80"/>
|
||||
<source>lists-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="87"/>
|
||||
<source>bulletins-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="94"/>
|
||||
<source>puzzle-game-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PeerSettingsPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="29"/>
|
||||
<source>address-label</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="40"/>
|
||||
<source>copy-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="44"/>
|
||||
<source>copied-to-clipboard-notification</source>
|
||||
<extracomment>notification: copied to clipboard</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="51"/>
|
||||
<source>display-name-label</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="60"/>
|
||||
<source>save-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="71"/>
|
||||
<source>delete-btn</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SettingsPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="17"/>
|
||||
<source>cwtch-settings-title</source>
|
||||
<extracomment>Cwtch Settings title</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="28"/>
|
||||
<source>zoom-label</source>
|
||||
<extracomment>Interface zoom (mostly affects text and button sizes)</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="44"/>
|
||||
<source>large-text-label</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="50"/>
|
||||
<source>default-scaling-text</source>
|
||||
<extracomment>"Default size text (scale factor: "</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="54"/>
|
||||
<source>small-text-label</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
Binary file not shown.
|
@ -0,0 +1,289 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="en_US">
|
||||
<context>
|
||||
<name>AddGroupPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/AddGroupPane.qml" line="17"/>
|
||||
<source>create-group-title</source>
|
||||
<translation>Create Group</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/AddGroupPane.qml" line="27"/>
|
||||
<source>server-label</source>
|
||||
<extracomment>Server label</extracomment>
|
||||
<translation>Server</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/AddGroupPane.qml" line="38"/>
|
||||
<source>group-name-label</source>
|
||||
<extracomment>Group name label</extracomment>
|
||||
<translation>Group name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/AddGroupPane.qml" line="45"/>
|
||||
<source>default-group-name</source>
|
||||
<extracomment>default suggested group name</extracomment>
|
||||
<translation>Awesome Group</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/AddGroupPane.qml" line="50"/>
|
||||
<source>create-group-btn</source>
|
||||
<extracomment>create group button</extracomment>
|
||||
<translation>Create</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BulletinOverlay</name>
|
||||
<message>
|
||||
<location filename="../qml/overlays/BulletinOverlay.qml" line="181"/>
|
||||
<source>new-bulletin-label</source>
|
||||
<translation>New Bulletin</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/overlays/BulletinOverlay.qml" line="193"/>
|
||||
<source>post-new-bulletin-label</source>
|
||||
<extracomment>Post a new Bulletin Post</extracomment>
|
||||
<translation>Post new bulletin</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/overlays/BulletinOverlay.qml" line="199"/>
|
||||
<source>title-placeholder</source>
|
||||
<extracomment>title place holder text</extracomment>
|
||||
<translation>title...</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>GroupSettingsPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="30"/>
|
||||
<source>server-label</source>
|
||||
<translation>Server</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="41"/>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="62"/>
|
||||
<source>copy-btn</source>
|
||||
<translation>Copy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="51"/>
|
||||
<source>invitation-label</source>
|
||||
<translation>Invitation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="72"/>
|
||||
<source>group-name-label</source>
|
||||
<translation>Group Name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="81"/>
|
||||
<source>save-btn</source>
|
||||
<translation>Save</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="91"/>
|
||||
<source>invite-to-group-label</source>
|
||||
<extracomment>Invite someone to the group</extracomment>
|
||||
<translation>Invite to group</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="102"/>
|
||||
<source>invite-btn</source>
|
||||
<translation>Invite</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/GroupSettingsPane.qml" line="111"/>
|
||||
<source>delete-btn</source>
|
||||
<translation>Delete</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ListOverlay</name>
|
||||
<message>
|
||||
<location filename="../qml/overlays/ListOverlay.qml" line="162"/>
|
||||
<source>add-list-item</source>
|
||||
<extracomment>Add a New List Item</extracomment>
|
||||
<translation>Add a New List Item</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/overlays/ListOverlay.qml" line="174"/>
|
||||
<source>add-new-item</source>
|
||||
<extracomment>Add a new item to the list</extracomment>
|
||||
<translation>Add a new item to the list</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/overlays/ListOverlay.qml" line="180"/>
|
||||
<source>todo-placeholder</source>
|
||||
<extracomment>Todo... placeholder text</extracomment>
|
||||
<translation>Todo...</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MembershipOverlay</name>
|
||||
<message>
|
||||
<location filename="../qml/overlays/MembershipOverlay.qml" line="21"/>
|
||||
<source>membership-description</source>
|
||||
<extracomment>Below is a list of users who have sent messages to the group. This list may not reflect all users who have access to the group.</extracomment>
|
||||
<translation>Below is a list of users who have sent messages to the group. This list may not reflect all users who have access to the group.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Message</name>
|
||||
<message>
|
||||
<location filename="../qml/widgets/Message.qml" line="55"/>
|
||||
<source>dm-tooltip</source>
|
||||
<extracomment>Click to DM</extracomment>
|
||||
<translation>Click to DM</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/Message.qml" line="154"/>
|
||||
<source>could-not-send-msg-error</source>
|
||||
<extracomment>Could not send this message</extracomment>
|
||||
<translation>Could not send this message</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/Message.qml" line="154"/>
|
||||
<source>acknowledged-label</source>
|
||||
<translation>Acknowledged</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/Message.qml" line="154"/>
|
||||
<source>pending-label</source>
|
||||
<translation>Pending</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MyProfile</name>
|
||||
<message>
|
||||
<location filename="../qml/widgets/MyProfile.qml" line="169"/>
|
||||
<source>copy-btn</source>
|
||||
<extracomment>Button for copying profile onion address to clipboard</extracomment>
|
||||
<translation>Copy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/MyProfile.qml" line="173"/>
|
||||
<source>copied-clipboard-notification</source>
|
||||
<extracomment>Copied to clipboard</extracomment>
|
||||
<translation>Copied to clipboard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/MyProfile.qml" line="203"/>
|
||||
<source>new-group-btn</source>
|
||||
<extracomment>create new group button</extracomment>
|
||||
<translation>Create new group</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/widgets/MyProfile.qml" line="213"/>
|
||||
<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>
|
||||
</context>
|
||||
<context>
|
||||
<name>OverlayPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="44"/>
|
||||
<source>accept-group-invite-label</source>
|
||||
<extracomment>Do you want to accept the invitation to $GROUP</extracomment>
|
||||
<translation>Do you want to accept the invitation to</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="49"/>
|
||||
<source>accept-group-btn</source>
|
||||
<extracomment>Accept group invite button</extracomment>
|
||||
<translation>Accept</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="59"/>
|
||||
<source>reject-group-btn</source>
|
||||
<extracomment>Reject Group invite button</extracomment>
|
||||
<translation>Reject</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="73"/>
|
||||
<source>chat-btn</source>
|
||||
<translation>Chat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="80"/>
|
||||
<source>lists-btn</source>
|
||||
<translation>Lists</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="87"/>
|
||||
<source>bulletins-btn</source>
|
||||
<translation>Bulletins</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/OverlayPane.qml" line="94"/>
|
||||
<source>puzzle-game-btn</source>
|
||||
<translation>Puzzle Game</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PeerSettingsPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="29"/>
|
||||
<source>address-label</source>
|
||||
<translation>Address</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="40"/>
|
||||
<source>copy-btn</source>
|
||||
<translation>Copy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="44"/>
|
||||
<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="51"/>
|
||||
<source>display-name-label</source>
|
||||
<translation>Display Name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="60"/>
|
||||
<source>save-btn</source>
|
||||
<translation>Save</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/PeerSettingsPane.qml" line="71"/>
|
||||
<source>delete-btn</source>
|
||||
<translation>Delete</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SettingsPane</name>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="17"/>
|
||||
<source>cwtch-settings-title</source>
|
||||
<extracomment>Cwtch Settings title</extracomment>
|
||||
<translation>Cwtch Settings</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="28"/>
|
||||
<source>zoom-label</source>
|
||||
<extracomment>Interface zoom (mostly affects text and button sizes)</extracomment>
|
||||
<translation>Interface zoon (mostly affects text and button sizes)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="44"/>
|
||||
<source>large-text-label</source>
|
||||
<translation type="unfinished">Large</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="50"/>
|
||||
<source>default-scaling-text</source>
|
||||
<extracomment>"Default size text (scale factor: "</extracomment>
|
||||
<translation>Default size text (scale factor:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qml/panes/SettingsPane.qml" line="54"/>
|
||||
<source>small-text-label</source>
|
||||
<translation>Small</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
6
main.go
6
main.go
|
@ -57,6 +57,10 @@ func main() {
|
|||
app := gui.NewQGuiApplication(len(os.Args), os.Args)
|
||||
app.SetWindowIcon(gui.NewQIcon5(":/qml/images/cwtch-icon.png"))
|
||||
|
||||
var translator = core.NewQTranslator(nil)
|
||||
translator.Load("translation_"+core.QLocale_System().Name(), ":/i18n/", "", "")
|
||||
core.QCoreApplication_InstallTranslator(translator)
|
||||
|
||||
core.QCoreApplication_SetAttribute(core.Qt__AA_EnableHighDpiScaling, true)
|
||||
quickcontrols2.QQuickStyle_SetStyle("Universe")
|
||||
engine := qml.NewQQmlApplicationEngine(nil)
|
||||
|
@ -111,7 +115,7 @@ func main() {
|
|||
|
||||
// these are long-lived pollers/listeners for incoming messages and status changes
|
||||
loadCwtchData(gcd, acn)
|
||||
go characters.IncomingListener(gcd.UIState.AddMessage, gcd.UIState.AddGroupError)
|
||||
go characters.IncomingListener(gcd.UIState.AddMessage, gcd.UIState.AddSendMessageError)
|
||||
go characters.TorStatusPoller(gcd.TorStatus, acn)
|
||||
go characters.PresencePoller(gcd.UIState.GetContact, gcd.UIState.AddContact, gcd.UIState.UpdateContact)
|
||||
go characters.GroupPoller(gcd.UIState.GetContact, gcd.UIState.UpdateContact)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>qml/overlays/BulletinOverlay.qml</file>
|
||||
<file>qml/overlays/ChatOverlay.qml</file>
|
||||
<file>qml/overlays/Game1Overlay.qml</file>
|
||||
<file>qml/overlays/Game2Overlay.qml</file>
|
||||
<file>qml/overlays/ListOverlay.qml</file>
|
||||
<file>qml/overlays/MembershipOverlay.qml</file>
|
||||
<file>qml/main.qml</file>
|
||||
<file>qml/panes/AddGroupPane.qml</file>
|
||||
<file>qml/panes/GroupSettingsPane.qml</file>
|
||||
<file>qml/panes/OverlayPane.qml</file>
|
||||
<file>qml/panes/PeerSettingsPane.qml</file>
|
||||
<file>qml/panes/SettingsPane.qml</file>
|
||||
<file>qml/styles/CwtchComboBoxStyle.qml</file>
|
||||
<file>qml/styles/CwtchExpandingButton.qml</file>
|
||||
<file>qml/styles/CwtchTextAreaStyle.qml</file>
|
||||
<file>qml/styles/CwtchTextFieldStyle.qml</file>
|
||||
<file>qml/widgets/ContactList.qml</file>
|
||||
<file>qml/widgets/ContactPicture.qml</file>
|
||||
<file>qml/widgets/ContactRow.qml</file>
|
||||
<file>qml/widgets/FontAwesome.qml</file>
|
||||
<file>qml/widgets/InplaceEditText.qml</file>
|
||||
<file>qml/widgets/Message.qml</file>
|
||||
<file>qml/widgets/MyProfile.qml</file>
|
||||
<file>qml/widgets/ScalingLabel.qml</file>
|
||||
<file>qml/widgets/SimpleButton.qml</file>
|
||||
<file>qml/widgets/StackToolbar.qml</file>
|
||||
<file>qml/widgets/controls/Button.qml</file>
|
||||
<file>qml/widgets/controls/Loader.qml</file>
|
||||
<file>qml/widgets/controls/Text.qml</file>
|
||||
<file>qml/widgets/controls/Variables.qml</file>
|
||||
<file>i18n/translation_en.qm</file>
|
||||
<file>i18n/translation_de.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -120,7 +120,7 @@ ApplicationWindow {
|
|||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: Layout.maximumWidth
|
||||
Layout.maximumWidth: theStack.pane == theStack.emptyPane ? parent.width : 450
|
||||
visible: (ratio <= 1.08 && windowItem.width >= 500) || theStack.pane == theStack.emptyPane
|
||||
visible: (ratio <= 1.08 && windowItem.width >= 700) || theStack.pane == theStack.emptyPane
|
||||
|
||||
|
||||
ContactList{
|
||||
|
|
|
@ -59,7 +59,7 @@ ColumnLayout {
|
|||
jsonModel4.clear()
|
||||
}
|
||||
|
||||
onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts) {
|
||||
onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts, ack, error) {
|
||||
var msg
|
||||
try {
|
||||
msg = JSON.parse(message)
|
||||
|
@ -178,7 +178,7 @@ ColumnLayout {
|
|||
}
|
||||
|
||||
GroupBox {
|
||||
title: qsTr("New Bulletin")
|
||||
title: qsTr("new-bulletin-label")
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
|
@ -189,12 +189,14 @@ ColumnLayout {
|
|||
|
||||
|
||||
Text {
|
||||
text: "Post a new Bulletin Post"
|
||||
//: Post a new Bulletin Post
|
||||
text: qsTr("post-new-bulletin-label")
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: newposttitle
|
||||
placeholderText: "Title.."
|
||||
//: title place holder text
|
||||
placeholderText: qsTr("title-placeholder")
|
||||
Layout.fillWidth: true
|
||||
style: CwtchTextFieldStyle{}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ ColumnLayout {
|
|||
txtMessage.text = ""
|
||||
}
|
||||
|
||||
onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts, ackd) {
|
||||
onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts, ackd, error) {
|
||||
var msg
|
||||
try {
|
||||
msg = JSON.parse(message)
|
||||
|
@ -52,6 +52,7 @@ ColumnLayout {
|
|||
"_fromMe": fromMe,
|
||||
"_ts": ts,
|
||||
"_ackd": ackd,
|
||||
"_error": error == true ? "this message failed to send" : "",
|
||||
})
|
||||
|
||||
|
||||
|
@ -93,6 +94,7 @@ ColumnLayout {
|
|||
fromMe: _fromMe
|
||||
timestamp: _ts
|
||||
ackd: _ackd
|
||||
error: _error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ ColumnLayout {
|
|||
jsonModel4.clear()
|
||||
}
|
||||
|
||||
onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts) {
|
||||
onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts, ack, error) {
|
||||
var msg
|
||||
try {
|
||||
msg = JSON.parse(message)
|
||||
|
@ -158,7 +158,8 @@ ColumnLayout {
|
|||
}
|
||||
|
||||
GroupBox {
|
||||
title: qsTr("Add a New List Item")
|
||||
//: Add a New List Item
|
||||
title: qsTr("add-list-item")
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
|
@ -169,12 +170,14 @@ ColumnLayout {
|
|||
|
||||
|
||||
Text {
|
||||
text: "Add a new item to the list"
|
||||
//: Add a new item to the list
|
||||
text: qsTr("add-new-item")
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: newposttitle
|
||||
placeholderText: "Todo.."
|
||||
//: Todo... placeholder text
|
||||
placeholderText: qsTr("todo-placeholder")
|
||||
Layout.fillWidth: true
|
||||
style: CwtchTextFieldStyle{}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
import QtGraphicalEffects 1.0
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.4
|
||||
import QtQuick.Controls.Material 2.0
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import "../widgets"
|
||||
import "../widgets/controls" as Awesome
|
||||
import "../fonts/Twemoji.js" as T
|
||||
import "../utils.js" as Utils
|
||||
import "../styles"
|
||||
|
||||
ColumnLayout {
|
||||
Text {
|
||||
wrapMode: Text.Wrap
|
||||
Layout.maximumWidth: parent.width
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
padding: 1
|
||||
//: Below is a list of users who have sent messages to the group. This list may not reflect all users who have access to the group.
|
||||
text: qsTr("membership-description")
|
||||
}
|
||||
|
||||
Flickable { // THE ACTUAL CONTACT LIST
|
||||
id: sv
|
||||
//Layout.alignment: Qt.AlignLeft | Qt.AlignTop
|
||||
clip: true
|
||||
Layout.minimumHeight: 100
|
||||
//Layout.maximumHeight: parent.height - 30
|
||||
Layout.fillHeight: true
|
||||
Layout.minimumWidth: parent.width
|
||||
Layout.maximumWidth: parent.width
|
||||
contentWidth: colContacts.width
|
||||
contentHeight: colContacts.height
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
maximumFlickVelocity: 400
|
||||
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
policy: ScrollBar.AlwaysOn
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: colContacts
|
||||
width: sv.width
|
||||
spacing: 0
|
||||
|
||||
Connections { // ADD/REMOVE CONTACT ENTRIES
|
||||
target: gcd
|
||||
|
||||
onClearMessages: function() {
|
||||
contactsModel.clear()
|
||||
}
|
||||
|
||||
onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts, ack, error) {
|
||||
var msg
|
||||
try {
|
||||
msg = JSON.parse(message)
|
||||
} catch (e) {
|
||||
return
|
||||
}
|
||||
|
||||
if (from == "me") {
|
||||
return
|
||||
}
|
||||
|
||||
for(var i = 0; i<contactsModel.count;i++){
|
||||
if(contactsModel.get(i)["_handle"] == handle) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (fromMe) {
|
||||
contactsModel.append({
|
||||
"_handle": handle,
|
||||
"_displayName": "me",
|
||||
"_image": image,
|
||||
})
|
||||
} else {
|
||||
contactsModel.append({
|
||||
"_handle": handle,
|
||||
"_displayName": displayName == "" ? handle : displayName,
|
||||
"_image": image,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListModel { // CONTACT OBJECTS ARE STORED HERE ...
|
||||
id: contactsModel
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: contactsModel // ... AND DISPLAYED HERE
|
||||
delegate: ContactRow {
|
||||
handle: _handle
|
||||
displayName: _displayName
|
||||
image: _image
|
||||
trusted: true
|
||||
background: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ ColumnLayout { // settingsPane
|
|||
|
||||
|
||||
StackToolbar {
|
||||
text: "Create a new group"
|
||||
text: qsTr("create-group-title")
|
||||
aux.visible: false
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,8 @@ ColumnLayout { // settingsPane
|
|||
spacing: 5
|
||||
|
||||
ScalingLabel {
|
||||
text: "Server:"
|
||||
//: Server label
|
||||
text: qsTr("server-label") + ":"
|
||||
}
|
||||
|
||||
TextField {
|
||||
|
@ -33,17 +34,20 @@ ColumnLayout { // settingsPane
|
|||
}
|
||||
|
||||
ScalingLabel{
|
||||
text: "Group name:"
|
||||
//: Group name label
|
||||
text: qsTr("group-name-label") + ":"
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: txtGroupName
|
||||
style: CwtchTextFieldStyle{ width: 400 }
|
||||
text: "my awesome group"
|
||||
//: default suggested group name
|
||||
text: qsTr("default-group-name")
|
||||
}
|
||||
|
||||
SimpleButton {
|
||||
text: "create"
|
||||
//: create group button
|
||||
text: qsTr("create-group-btn")
|
||||
|
||||
onClicked: {
|
||||
gcd.createGroup(txtServer.text, txtGroupName.text)
|
||||
|
|
|
@ -27,7 +27,7 @@ ColumnLayout { // groupSettingsPane
|
|||
spacing: 5
|
||||
|
||||
ScalingLabel {
|
||||
text: "Server:"
|
||||
text: qsTr("server-label") + ":"
|
||||
}
|
||||
|
||||
TextField {
|
||||
|
@ -38,17 +38,17 @@ ColumnLayout { // groupSettingsPane
|
|||
|
||||
SimpleButton {
|
||||
icon: "regular/clipboard"
|
||||
text: "copy"
|
||||
text: qsTr("copy-btn")
|
||||
|
||||
onClicked: {
|
||||
gcd.popup("copied to clipboard!")
|
||||
gcd.popup("copied-clipboard-notification")
|
||||
txtServer.selectAll()
|
||||
txtServer.copy()
|
||||
}
|
||||
}
|
||||
|
||||
ScalingLabel {
|
||||
text: "Invitation:"
|
||||
text: qsTr("invitation-label") + ":"
|
||||
}
|
||||
|
||||
TextField {
|
||||
|
@ -59,17 +59,17 @@ ColumnLayout { // groupSettingsPane
|
|||
|
||||
SimpleButton {
|
||||
icon: "regular/clipboard"
|
||||
text: "copy"
|
||||
text: qsTr("copy-btn")
|
||||
|
||||
onClicked: {
|
||||
gcd.popup("copied to clipboard!")
|
||||
gcd.popup("copied-clipboard-notification")
|
||||
txtInvitation.selectAll()
|
||||
txtInvitation.copy()
|
||||
}
|
||||
}
|
||||
|
||||
ScalingLabel{
|
||||
text: "Group name:"
|
||||
text: qsTr("group-name-label") + ":"
|
||||
}
|
||||
|
||||
TextField {
|
||||
|
@ -78,7 +78,7 @@ ColumnLayout { // groupSettingsPane
|
|||
}
|
||||
|
||||
SimpleButton {
|
||||
text: "Save"
|
||||
text: qsTr("save-btn")
|
||||
|
||||
onClicked: {
|
||||
gcd.saveGroupSettings(groupID, txtGroupName.text)
|
||||
|
@ -87,7 +87,8 @@ ColumnLayout { // groupSettingsPane
|
|||
}
|
||||
}
|
||||
|
||||
ScalingLabel { text: "Invite someone to the group:" }
|
||||
//: Invite someone to the group
|
||||
ScalingLabel { text: qsTr("invite-to-group-label") }
|
||||
|
||||
ComboBox {
|
||||
id: cbInvite
|
||||
|
@ -98,7 +99,7 @@ ColumnLayout { // groupSettingsPane
|
|||
}
|
||||
|
||||
SimpleButton {
|
||||
text: "Invite"
|
||||
text: qsTr("invite-btn")
|
||||
|
||||
onClicked: {
|
||||
gcd.inviteToGroup(addrbook[cbInvite.currentIndex], groupID)
|
||||
|
@ -107,7 +108,7 @@ ColumnLayout { // groupSettingsPane
|
|||
|
||||
SimpleButton {
|
||||
icon: "regular/trash-alt"
|
||||
text: "delete"
|
||||
text: qsTr("delete-btn")
|
||||
|
||||
onClicked: {
|
||||
gcd.leaveGroup(groupID)
|
||||
|
|
|
@ -13,10 +13,15 @@ ColumnLayout {
|
|||
id: overlay
|
||||
property string name
|
||||
property bool accepted
|
||||
property bool inGroup
|
||||
|
||||
|
||||
StackToolbar {
|
||||
id: toolbar
|
||||
//text: "open privacy exec"
|
||||
|
||||
membership.visible: gcd.currentOpenConversation.length == 32
|
||||
|
||||
membership.onClicked: overlayStack.overlay = overlayStack.membershipOverlay
|
||||
|
||||
aux.onClicked: {
|
||||
if (gcd.currentOpenConversation.length == 32) {
|
||||
|
@ -32,19 +37,26 @@ ColumnLayout {
|
|||
|
||||
RowLayout {
|
||||
visible:!overlay.accepted && (gcd.currentOpenConversation.length == 32)
|
||||
|
||||
|
||||
Text {
|
||||
text: "Do you want to accept the invitation to " + overlay.name + "?"
|
||||
//: Do you want to accept the invitation to $GROUP
|
||||
text: qsTr("accept-group-invite-label") + " " + overlay.name + "?"
|
||||
}
|
||||
|
||||
SimpleButton {
|
||||
text: "Accept"
|
||||
//: Accept group invite button
|
||||
text: qsTr("accept-group-btn")
|
||||
icon: "regular/heart"
|
||||
onClicked: {
|
||||
gcd.acceptGroup(gcd.currentOpenConversation)
|
||||
gcd.requestGroupSettings(gcd.currentOpenConversation)
|
||||
}
|
||||
}
|
||||
|
||||
SimpleButton {
|
||||
text: "Reject"
|
||||
//: Reject Group invite button
|
||||
text: qsTr("reject-group-btn")
|
||||
icon: "regular/trash-alt"
|
||||
onClicked: {
|
||||
gcd.leaveGroup(gcd.currentOpenConversation)
|
||||
|
@ -58,28 +70,28 @@ ColumnLayout {
|
|||
|
||||
|
||||
SimpleButton {
|
||||
text: "Chat"
|
||||
text: qsTr("chat-btn")
|
||||
|
||||
|
||||
onClicked: overlayStack.overlay = overlayStack.chatOverlay
|
||||
}
|
||||
|
||||
SimpleButton {
|
||||
text: "Lists"
|
||||
text: qsTr("lists-btn")
|
||||
|
||||
|
||||
onClicked: overlayStack.overlay = overlayStack.listOverlay
|
||||
}
|
||||
|
||||
SimpleButton {
|
||||
text: "Bulletins"
|
||||
text: qsTr("bulletins-btn")
|
||||
|
||||
|
||||
onClicked: overlayStack.overlay = overlayStack.bulletinOverlay
|
||||
}
|
||||
|
||||
SimpleButton {
|
||||
text: "Puzzle Game"
|
||||
text: qsTr("puzzle-game-btn")
|
||||
|
||||
|
||||
onClicked: overlayStack.overlay = overlayStack.game1Overlay
|
||||
|
@ -93,6 +105,7 @@ ColumnLayout {
|
|||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.top: switcher.bottom
|
||||
implicitHeight: height
|
||||
currentIndex: 0
|
||||
|
||||
property alias overlay: overlayStack.currentIndex
|
||||
|
@ -100,24 +113,48 @@ ColumnLayout {
|
|||
readonly property int listOverlay: 1
|
||||
readonly property int bulletinOverlay: 2
|
||||
readonly property int game1Overlay: 3
|
||||
readonly property int membershipOverlay: 4
|
||||
|
||||
|
||||
ChatOverlay {} //0
|
||||
ChatOverlay { //0
|
||||
Layout.maximumHeight: overlayStack.height
|
||||
Layout.maximumWidth: overlayStack.width
|
||||
}
|
||||
|
||||
ListOverlay{} //1
|
||||
ListOverlay{ //1
|
||||
Layout.maximumHeight: overlayStack.height
|
||||
Layout.maximumWidth: overlayStack.width
|
||||
}
|
||||
|
||||
BulletinOverlay{} //2
|
||||
BulletinOverlay{ //2
|
||||
Layout.maximumHeight: overlayStack.height
|
||||
Layout.maximumWidth: overlayStack.width
|
||||
}
|
||||
|
||||
Game1Overlay{} //3
|
||||
Game1Overlay{ //3
|
||||
Layout.maximumHeight: overlayStack.height
|
||||
Layout.maximumWidth: overlayStack.width
|
||||
}
|
||||
|
||||
MembershipOverlay { //4
|
||||
Layout.maximumHeight: overlayStack.height
|
||||
Layout.maximumWidth: overlayStack.width
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: gcd
|
||||
Connections {
|
||||
target: gcd
|
||||
|
||||
onSupplyGroupSettings: function(gid, name, server, invite, accepted, addrbooknames, addrbookaddrs) {
|
||||
console.log("Supplied " + gid + " " + name + "Accepted " + accepted)
|
||||
overlay.name = name
|
||||
overlay.accepted = accepted
|
||||
}
|
||||
}
|
||||
onResetMessagePane: function() {
|
||||
overlayStack.overlay = overlayStack.chatOverlay
|
||||
overlay.inGroup = false
|
||||
}
|
||||
|
||||
onSupplyGroupSettings: function(gid, name, server, invite, accepted, addrbooknames, addrbookaddrs) {
|
||||
console.log("Supplied " + gid + " " + name + "Accepted " + accepted)
|
||||
overlay.name = name
|
||||
overlay.accepted = accepted
|
||||
overlay.inGroup = true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ ColumnLayout { // peerSettingsPane
|
|||
spacing: 5
|
||||
|
||||
ScalingLabel {
|
||||
text: "Address:"
|
||||
text: qsTr("address-label")
|
||||
}
|
||||
|
||||
TextField {
|
||||
|
@ -37,17 +37,18 @@ ColumnLayout { // peerSettingsPane
|
|||
|
||||
SimpleButton {
|
||||
icon: "regular/clipboard"
|
||||
text: "copy"
|
||||
text: qsTr("copy-btn")
|
||||
|
||||
onClicked: {
|
||||
gcd.popup("copied to clipboard!")
|
||||
//: notification: copied to clipboard
|
||||
gcd.popup(qsTr("copied-to-clipboard-notification"))
|
||||
txtOnion.selectAll()
|
||||
txtOnion.copy()
|
||||
}
|
||||
}
|
||||
|
||||
ScalingLabel{
|
||||
text: "Display name:"
|
||||
text: qsTr("display-name-label")
|
||||
}
|
||||
|
||||
TextField {
|
||||
|
@ -56,7 +57,7 @@ ColumnLayout { // peerSettingsPane
|
|||
}
|
||||
|
||||
SimpleButton {
|
||||
text: "Save"
|
||||
text: qsTr("save-btn")
|
||||
|
||||
onClicked: {
|
||||
gcd.savePeerSettings(txtOnion.text, txtDisplayName.text)
|
||||
|
@ -67,7 +68,7 @@ ColumnLayout { // peerSettingsPane
|
|||
|
||||
SimpleButton {
|
||||
icon: "regular/trash-alt"
|
||||
text: "delete"
|
||||
text: qsTr("delete-btn")
|
||||
|
||||
onClicked: {
|
||||
gcd.setAttribute(txtOnion.text, "deleted", "deleted")
|
||||
|
|
|
@ -13,7 +13,8 @@ ColumnLayout { // settingsPane
|
|||
|
||||
|
||||
StackToolbar {
|
||||
text: "Cwtch Settings"
|
||||
//: Cwtch Settings title
|
||||
text: qsTr("cwtch-settings-title")
|
||||
aux.visible: false
|
||||
}
|
||||
|
||||
|
@ -23,7 +24,8 @@ ColumnLayout { // settingsPane
|
|||
|
||||
ScalingLabel {
|
||||
Layout.maximumWidth: parent.width
|
||||
text: "Interface zoom (mostly affects text and button sizes):"
|
||||
//: Interface zoom (mostly affects text and button sizes)
|
||||
text: qsTr("zoom-label") + ":"
|
||||
}
|
||||
|
||||
Slider {
|
||||
|
@ -39,16 +41,17 @@ ColumnLayout { // settingsPane
|
|||
}
|
||||
|
||||
ScalingLabel {
|
||||
text: "Large text"
|
||||
text: qsTr("large-text-label")
|
||||
size: 20
|
||||
}
|
||||
|
||||
ScalingLabel{
|
||||
text: "Default size text (scale factor: " + zoomSlider.value + ")"
|
||||
//: "Default size text (scale factor: "
|
||||
text: qsTr("default-scaling-text") + zoomSlider.value + ")"
|
||||
}
|
||||
|
||||
ScalingLabel {
|
||||
text: "Small text"
|
||||
text: qsTr("small-text-label")
|
||||
size: 8
|
||||
}
|
||||
|
||||
|
|
|
@ -16,55 +16,66 @@ Item {
|
|||
property int status
|
||||
property bool isGroup
|
||||
property bool showStatus
|
||||
|
||||
property bool highlight
|
||||
|
||||
Rectangle {
|
||||
id: mainImage
|
||||
width: 48
|
||||
height: 48
|
||||
color: "#FFFFFF"
|
||||
color: highlight ? windowItem.cwtch_dark_color: "#FFFFFF"
|
||||
radius: width / 2
|
||||
|
||||
Rectangle {
|
||||
width: highlight ? 44 : 48
|
||||
height: highlight ? 44 : 48
|
||||
color: "#FFFFFF"
|
||||
radius: width / 2
|
||||
anchors.centerIn:parent
|
||||
|
||||
Image { // PROFILE IMAGE
|
||||
id: img
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectFit
|
||||
visible: false
|
||||
}
|
||||
|
||||
Image { // CIRCLE MASK
|
||||
id: mask
|
||||
fillMode: Image.PreserveAspectFit
|
||||
visible: false
|
||||
source: "qrc:/qml/images/extra/clipcircle.png"
|
||||
}
|
||||
Image { // PROFILE IMAGE
|
||||
id: img
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectFit
|
||||
visible: false
|
||||
}
|
||||
|
||||
Image { // CIRCLE MASK
|
||||
id: mask
|
||||
fillMode: Image.PreserveAspectFit
|
||||
visible: false
|
||||
source: "qrc:/qml/images/extra/clipcircle.png"
|
||||
}
|
||||
|
||||
OpacityMask {
|
||||
anchors.fill: img
|
||||
source: img
|
||||
maskSource: mask
|
||||
}
|
||||
|
||||
OpacityMask {
|
||||
anchors.fill: img
|
||||
source: img
|
||||
maskSource: mask
|
||||
}
|
||||
|
||||
Rectangle { // PRESENCE INDICATOR
|
||||
visible: showStatus
|
||||
color: "#FFFFFF"
|
||||
width: 8
|
||||
height: 8
|
||||
radius: 2
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 4
|
||||
visible: showStatus
|
||||
color: "#FFFFFF"
|
||||
width: 8
|
||||
height: 8
|
||||
radius: 2
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 4
|
||||
|
||||
|
||||
Rectangle { //-2:WtfCodeError,-1:Untrusted,0:Disconnected,1:Connecting,2:Connected,3:Authenticated,4:Failed,5:Killed
|
||||
color: status == 3 ? "green" : status == -1 ? "blue" : status == 1 ? "orange" : status == 2 ? "orange" : "red"
|
||||
width: 5
|
||||
height: 5
|
||||
radius: 2
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 1.5
|
||||
}
|
||||
}
|
||||
Rectangle { //-2:WtfCodeError,-1:Untrusted,0:Disconnected,1:Connecting,2:Connected,3:Authenticated,4:Failed,5:Killed
|
||||
color: status == 3 ? "green" : status == -1 ? "blue" : status == 1 ? "orange" : status == 2 ? "orange" : "red"
|
||||
width: 5
|
||||
height: 5
|
||||
radius: 2
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.margins: 1.5
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ RowLayout { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
|
|||
property bool deleted
|
||||
property alias status: imgProfile.status
|
||||
property string server
|
||||
property bool background: true
|
||||
|
||||
|
||||
Rectangle { // CONTACT ENTRY BACKGROUND COLOR
|
||||
|
@ -28,7 +29,7 @@ RowLayout { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
|
|||
anchors.right: parent.right
|
||||
height: childrenRect.height + 3
|
||||
width: parent.width
|
||||
color: isHover ? "#D2D2F3" : (isActive ? "#D2D2F3" : "#D2C0DD")
|
||||
color: background ? (isHover ? "#D2D2F3" : (isActive ? "#D2D2F3" : "#D2C0DD")) : windowItem.cwtch_background_color
|
||||
|
||||
|
||||
RowLayout {
|
||||
|
|
|
@ -35,12 +35,10 @@ RowLayout {
|
|||
}
|
||||
|
||||
onGroupSendError: function(mid, error) {
|
||||
console.log("Error " + mid + " " + messageID)
|
||||
if (mid == messageID) {
|
||||
root.error = error
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,9 +48,18 @@ RowLayout {
|
|||
handle: root.from
|
||||
visible: !fromMe
|
||||
showStatus: false
|
||||
highlight: ima.containsMouse
|
||||
|
||||
ToolTip.visible: ima.containsMouse
|
||||
//: Click to DM
|
||||
ToolTip.text: qsTr("dm-tooltip")
|
||||
|
||||
MouseArea {
|
||||
id: ima
|
||||
anchors.fill: parent
|
||||
hoverEnabled: overlay.inGroup
|
||||
|
||||
|
||||
onClicked: {
|
||||
gcd.broadcast("ResetMessagePane")
|
||||
theStack.pane = theStack.messagePane
|
||||
|
@ -143,7 +150,8 @@ RowLayout {
|
|||
sourceSize.height: 10
|
||||
visible: fromMe
|
||||
ToolTip.visible: ma.containsMouse
|
||||
ToolTip.text: root.error != "" ? qsTr("Could not send this message: ") + qsTr(root.error) : (root.ackd ? qsTr("Acknowledged") : qsTr("Pending"))
|
||||
//: Could not send this message
|
||||
ToolTip.text: root.error != "" ? qsTr("could-not-send-msg-error") + ":" + root.error : (root.ackd ? qsTr("acknowledged-label") : qsTr("pending-label"))
|
||||
MouseArea {
|
||||
id: ma
|
||||
anchors.fill: parent
|
||||
|
|
|
@ -165,10 +165,12 @@ ColumnLayout {
|
|||
|
||||
SimpleButton { // COPY ONION ADDRESS BUTTON
|
||||
icon: "regular/clipboard"
|
||||
text: "copy"
|
||||
//: Button for copying profile onion address to clipboard
|
||||
text: qsTr("copy-btn")
|
||||
|
||||
onClicked: {
|
||||
gcd.popup("copied to clipboard!")
|
||||
//: Copied to clipboard
|
||||
gcd.popup(qsTr("copied-clipboard-notification"))
|
||||
txtHidden.text = nick.replace(" ", "~") + "~" + onion
|
||||
txtHidden.selectAll()
|
||||
txtHidden.copy()
|
||||
|
@ -197,7 +199,8 @@ ColumnLayout {
|
|||
|
||||
SimpleButton { // CREATE GROUP BUTTON
|
||||
icon: "regular/clipboard"
|
||||
text: "new group"
|
||||
//: create new group button
|
||||
text: qsTr("new-group-btn")
|
||||
|
||||
onClicked: theStack.pane = theStack.addGroupPane
|
||||
}
|
||||
|
@ -206,7 +209,8 @@ ColumnLayout {
|
|||
TextField {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
style: CwtchTextFieldStyle{ width: 400 }
|
||||
placeholderText: "... paste an address here to add a contact ..."
|
||||
//: ex: "... paste an address here to add a contact ..."
|
||||
placeholderText: qsTr("paste-address-to-add-contact")
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
|
||||
onTextChanged: {
|
||||
|
|
|
@ -26,6 +26,7 @@ Rectangle {
|
|||
property alias font: buttonText.font.family
|
||||
property string icon
|
||||
property bool mousedown
|
||||
property string tooltip
|
||||
signal clicked
|
||||
|
||||
|
||||
|
@ -48,6 +49,9 @@ Rectangle {
|
|||
anchors.leftMargin: 6
|
||||
visible: button.text != "" && button.text != undefined
|
||||
}
|
||||
|
||||
ToolTip.visible: tooltip != "" && mouseArea.containsMouse
|
||||
ToolTip.text: tooltip
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,6 +67,8 @@ Rectangle {
|
|||
onPressed: mousedown = true
|
||||
|
||||
onReleased: mousedown = false
|
||||
|
||||
hoverEnabled: true
|
||||
}
|
||||
|
||||
Keys.onSpacePressed: clicked()
|
||||
|
|
|
@ -20,6 +20,7 @@ Rectangle { // OVERHEAD BAR ON STACK PANE
|
|||
property alias text: lbl.text
|
||||
property alias aux: btnAux
|
||||
property alias back: btnBack
|
||||
property alias membership: btnMembership
|
||||
|
||||
|
||||
SimpleButton {// BACK BUTTON
|
||||
|
@ -38,11 +39,21 @@ Rectangle { // OVERHEAD BAR ON STACK PANE
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
SimpleButton { // COG BUTTON
|
||||
id: btnAux
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
RowLayout {
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 6
|
||||
icon: "solid/cog"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
SimpleButton { // Membership Button
|
||||
id: btnMembership
|
||||
icon: "solid/users"
|
||||
tooltip: "View Group Membership"
|
||||
}
|
||||
|
||||
SimpleButton { // COG BUTTON
|
||||
id: btnAux
|
||||
icon: "solid/cog"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
QT += quick
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which as been marked deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
main.go
|
||||
|
||||
RESOURCES += qml.qrc
|
||||
|
||||
TRANSLATIONS = i18n/translation_en.ts \
|
||||
i18n/translation_de.ts
|
||||
|
||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||
QML_IMPORT_PATH =
|
||||
|
||||
# Additional import path used to resolve QML modules just for Qt Quick Designer
|
||||
QML_DESIGNER_IMPORT_PATH =
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
Loading…
Reference in New Issue