new qmlfmt script and test application to main.qml
the build was successful Details

This commit is contained in:
Dan Ballard 2020-04-27 14:55:10 -07:00
parent 1319674940
commit 1af5662416
45 changed files with 2556 additions and 2462 deletions

86
cmd/qmlfmt/main.go Normal file
View File

@ -0,0 +1,86 @@
package main
import (
"bufio"
"log"
"os"
"strings"
)
const (
indent = " "
)
func main() {
if len(os.Args) < 2 {
log.Fatal("Required argument(s): filename(s)")
}
for _, filename := range os.Args[1:] {
processFile(filename)
}
}
func processFile(filename string) {
file, err := os.Open(filename)
if err != nil {
log.Fatalf("Could not read file %v: %v\n", filename, err)
}
scanner := bufio.NewScanner(file)
var lines []string
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
file.Close()
file, err = os.Create(filename)
defer file.Close()
if err != nil {
log.Fatalf("Could not write to file %v: %v\n", filename, err)
}
indentCount := 0
inMultiLineComment := false
for _, line := range lines {
singleCommentPos := strings.Index(line, "//")
multiLineCommentStartPos := strings.Index(line, "/*")
multiLineCommentEndPos := strings.Index(line, "*/")
closePos := strings.Index(line, "}")
if !inMultiLineComment && closePos > -1 && (singleCommentPos == -1 || closePos < singleCommentPos) &&
(multiLineCommentStartPos == -1 || closePos < multiLineCommentStartPos) &&
(multiLineCommentEndPos == -1 || closePos > multiLineCommentEndPos) {
indentCount--
}
trimedLine := strings.Trim(line, " \t")
if trimedLine == "" {
file.Write([]byte("\n"))
} else {
file.Write([]byte(strings.Repeat(indent, indentCount) + trimedLine + "\n"))
}
openPos := strings.Index(line, "{")
if !inMultiLineComment && openPos > -1 && (singleCommentPos == -1 || openPos < singleCommentPos) &&
(multiLineCommentStartPos == -1 || openPos < multiLineCommentStartPos) &&
(multiLineCommentEndPos == -1 || openPos > multiLineCommentEndPos) {
indentCount++
}
if multiLineCommentStartPos > -1 {
inMultiLineComment = true
}
if multiLineCommentEndPos > -1 {
inMultiLineComment = false
}
}
}

View File

@ -1,6 +1,6 @@
pragma Singleton
import QtQuick 2.5
import QtQuick 2.5
QtObject {
@ -24,4 +24,4 @@ QtObject {
source: "qrc:/qml/fonts/opensans/OpenSans-Light.ttf"
}
}
}

View File

@ -17,61 +17,61 @@ import "utils.js" as Utils
ApplicationWindow {
id: windowItem
width: 1200
height: 800
visible: true
title: "cwtch" + ""
id: windowItem
width: 1200
height: 800
visible: true
title: "cwtch" + ""
font.family: Fonts.applicationFontRegular.name
font.styleName: "Light"
readonly property real ratio: height / width
readonly property real ratio: height / width
readonly property string cwtch_background_color: '#FF0000'
readonly property string cwtch_color: '#00FF00'
readonly property string cwtch_dark_color: '#0000FF'
readonly property string cwtch_background_color: '#FF0000'
readonly property string cwtch_color: '#00FF00'
readonly property string cwtch_dark_color: '#0000FF'
FontAwesome { // PRETTY BUTTON ICONS
id: awesome
resource: "qrc:/qml/fonts/fontawesome.ttf"
}
FontAwesome { // PRETTY BUTTON ICONS
id: awesome
resource: "qrc:/qml/fonts/fontawesome.ttf"
}
FontLoader {
source: "qrc:/qml/fonts/AdobeBlank.ttf"
}
FontLoader {
source: "qrc:/qml/fonts/AdobeBlank.ttf"
}
function parse(text, size, isntEditable) { // REPLACE EMOJI WITH <IMG> TAGS
T.twemoji.base = gcd.assetPath + "twemoji/"
T.twemoji.ext = ".png"
T.twemoji.size = "72x72"
T.twemoji.className = "\" height=\""+size+"\" width=\""+size
var retText = T.twemoji.parse(Utils.htmlEscaped(text))
retText = retText.replace(/\n/g,"<br/>")
function parse(text, size, isntEditable) { // REPLACE EMOJI WITH <IMG> TAGS
T.twemoji.base = gcd.assetPath + "twemoji/"
T.twemoji.ext = ".png"
T.twemoji.size = "72x72"
T.twemoji.className = "\" height=\""+size+"\" width=\""+size
var retText = T.twemoji.parse(Utils.htmlEscaped(text))
retText = retText.replace(/\n/g,"<br/>")
// mutant standard stickers
if (isntEditable) retText = Mutant.standard.parse(retText)
// mutant standard stickers
if (isntEditable) retText = Mutant.standard.parse(retText)
return retText
}
return retText
}
function restoreEmoji(text) { // REPLACE <IMG> TAGS WITH EMOJI
var re = RegExp('<img src="' + gcd.assetPath + 'twemoji/72x72/([^"]*?)\.png" width="10" height="10" \/>', 'g')
var arr
var newtext = text
while (arr = re.exec(text)) {
var pieces = arr[1].split("-")
var replacement = ""
for (var i = 0; i < pieces.length; i++) {
replacement += T.twemoji.convert.fromCodePoint(pieces[i])
}
newtext = newtext.replace(arr[0], replacement)
}
return newtext
}
function restoreEmoji(text) { // REPLACE <IMG> TAGS WITH EMOJI
var re = RegExp('<img src="' + gcd.assetPath + 'twemoji/72x72/([^"]*?)\.png" width="10" height="10" \/>', 'g')
var arr
var newtext = text
while (arr = re.exec(text)) {
var pieces = arr[1].split("-")
var replacement = ""
for (var i = 0; i < pieces.length; i++) {
replacement += T.twemoji.convert.fromCodePoint(pieces[i])
}
newtext = newtext.replace(arr[0], replacement)
}
return newtext
}
function ptToPx(pt) {
return Screen.pixelDensity * 25.4 * pt / 72
@ -109,14 +109,14 @@ ApplicationWindow {
}
Rectangle { // Profile login/management pane
anchors.fill: parent
visible: false
color: Theme.backgroundMainColor
anchors.fill: parent
visible: false
color: Theme.backgroundMainColor
ProfileManagerPane {
id: profilesPane
anchors.fill: parent
}
ProfileManagerPane {
id: profilesPane
anchors.fill: parent
}
}
Rectangle { // Profile login/management pane
@ -171,20 +171,20 @@ ApplicationWindow {
property string title
Item { anchors.fill: parent } // empty
Item { anchors.fill: parent } // empty
OverlayPane { // messagePane
title: theStack.title
anchors.fill: parent
}
SettingsPane{ anchors.fill: parent }
SettingsPane{ anchors.fill: parent }
PeerSettingsPane { anchors.fill: parent }
PeerSettingsPane { anchors.fill: parent }
GroupSettingsPane{ anchors.fill: parent }
GroupSettingsPane{ anchors.fill: parent }
AddGroupPane { anchors.fill: parent }
AddGroupPane { anchors.fill: parent }
}
}
}
@ -202,56 +202,56 @@ ApplicationWindow {
}
}
}
}
}
PropertyAnimation { id: anmPopup; easing.type: Easing.InQuart; duration: 7000; target: popup; property: "opacity"; to: 0; }
PropertyAnimation { id: anmPopup; easing.type: Easing.InQuart; duration: 7000; target: popup; property: "opacity"; to: 0; }
Rectangle { // THE ERROR MESSAGE POPUP
id: popup
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 20
width: lblPopup.width + 30
height: lblPopup.height + 8 * gcd.themeScale
color: "#000000"
opacity: 0.5
radius: 15
visible: false
Rectangle { // THE ERROR MESSAGE POPUP
id: popup
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 20
width: lblPopup.width + 30
height: lblPopup.height + 8 * gcd.themeScale
color: "#000000"
opacity: 0.5
radius: 15
visible: false
Label {
id: lblPopup
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 18 * gcd.themeScale
color: "#FFFFFF"
}
}
Label {
id: lblPopup
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 18 * gcd.themeScale
color: "#FFFFFF"
}
}
Connections { // POPUPS ARE INVOKED BY GO FUNCS
target: gcd
Connections { // POPUPS ARE INVOKED BY GO FUNCS
target: gcd
onInvokePopup: function(str) {
lblPopup.text = str
popup.opacity = 0.5
popup.visible = true
anmPopup.restart()
}
onInvokePopup: function(str) {
lblPopup.text = str
popup.opacity = 0.5
popup.visible = true
anmPopup.restart()
}
onSetToolbarTitle: function(str) {
theStack.title = str
}
onSetToolbarTitle: function(str) {
theStack.title = str
}
onLoaded: function() {
parentStack.pane = parentStack.managementPane
onLoaded: function() {
parentStack.pane = parentStack.managementPane
splashPane.running = false
}
}
}
Component.onCompleted: Mutant.standard.imagePath = gcd.assetPath;
Component.onCompleted: Mutant.standard.imagePath = gcd.assetPath;
Connections {
Connections {
target: Qt.application
onStateChanged: function() {
// https://doc.qt.io/qt-5/qt.html#ApplicationState-enum

View File

@ -12,51 +12,51 @@ import "../utils.js" as Utils
import "../styles"
ColumnLayout {
Layout.fillWidth: true
width:parent.width
Layout.fillWidth: true
width:parent.width
Text {
Layout.fillWidth: true
}
Text {
Layout.fillWidth: true
}
TextField {
id: filter
TextField {
id: filter
placeholderText: "Search.."
placeholderText: "Search.."
style: CwtchTextFieldStyle{}
style: CwtchTextFieldStyle{}
anchors.left: parent.left
anchors.right: parent.right
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 10
anchors.margins: 10
onTextChanged: {
bulletinView.filter = text
if (bulletinView.model.get(bulletinView.currentIndex).title.indexOf(text) == -1) {
bulletinView.currentIndex = -1
}
}
}
onTextChanged: {
bulletinView.filter = text
if (bulletinView.model.get(bulletinView.currentIndex).title.indexOf(text) == -1) {
bulletinView.currentIndex = -1
}
}
}
Flickable { // THE MESSAGE LIST ITSELF
id: sv
clip: true
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
Layout.fillHeight: true
Layout.fillWidth: true
contentWidth: parent.width
contentHeight: parent.height
boundsBehavior: Flickable.StopAtBounds
maximumFlickVelocity: 800
Flickable { // THE MESSAGE LIST ITSELF
id: sv
clip: true
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
Layout.fillHeight: true
Layout.fillWidth: true
contentWidth: parent.width
contentHeight: parent.height
boundsBehavior: Flickable.StopAtBounds
maximumFlickVelocity: 800
Connections {
target: gcd
Connections {
target: gcd
onClearMessages: function() {
jsonModel4.clear()
}
onClearMessages: function() {
jsonModel4.clear()
}
onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts, ack, error) {
handler(handle, from, displayName, message, image, mid, fromMe, ts, ack, error)
@ -67,29 +67,29 @@ ColumnLayout {
}
function handler(handle, from, displayName, message, image, mid, fromMe, ts, ack, error) {
var msg
try {
msg = JSON.parse(message)
} catch (e) {
return
}
if (msg.o != 2) return
var msg
try {
msg = JSON.parse(message)
} catch (e) {
return
}
if (msg.o != 2) return
if (msg.t != undefined && msg.b != undefined) {
jsonModel4.insert(0,{
"title":msg.t,
"body": msg.b,
"selected":false,
"from": from,
"displayName": displayName,
"timestamp": ts
})
}
if (msg.t != undefined && msg.b != undefined) {
jsonModel4.insert(0,{
"title":msg.t,
"body": msg.b,
"selected":false,
"from": from,
"displayName": displayName,
"timestamp": ts
})
}
/*if (sv.contentY + sv.height >= sv.contentHeight - colMessages.height && sv.contentHeight > sv.height) {
sv.contentY = sv.contentHeight - sv.height
}*/
}
/*if (sv.contentY + sv.height >= sv.contentHeight - colMessages.height && sv.contentHeight > sv.height) {
sv.contentY = sv.contentHeight - sv.height
}*/
}
onUpdateContactStatus: function(_handle, _status, _loading) {
if (gcd.selectedConversation == _handle) {
@ -105,153 +105,153 @@ ColumnLayout {
}
}
}
}
ScrollBar.vertical: ScrollBar{
policy: ScrollBar.AlwaysOn
}
ScrollBar.vertical: ScrollBar{
policy: ScrollBar.AlwaysOn
}
ListView {
id: bulletinView
anchors.left: parent.left
anchors.leftMargin: 10
anchors.topMargin: 10
ListView {
id: bulletinView
anchors.left: parent.left
anchors.leftMargin: 10
anchors.topMargin: 10
width: parent.width - 50
height: parent.height - 20
orientation: Qt.Vertical
spacing: 10
model: jsonModel4
property string filter: ""
delegate:
width: parent.width - 50
height: parent.height - 20
orientation: Qt.Vertical
spacing: 10
model: jsonModel4
property string filter: ""
delegate:
Item {
width: parent.width
height: title.indexOf(bulletinView.filter) >= 0 ? (selected ? texttitle.height + textbody.height + replybtn.height + 8 : texttitle.height * 2) : 0
visible: title.indexOf(bulletinView.filter) >= 0
Item {
width: parent.width
height: title.indexOf(bulletinView.filter) >= 0 ? (selected ? texttitle.height + textbody.height + replybtn.height + 8 : texttitle.height * 2) : 0
visible: title.indexOf(bulletinView.filter) >= 0
Column {
width: parent.width
Column {
width: parent.width
RowLayout {
Button {
text: selected ? "-" : "+"
style: CwtchExpandingButton{}
}
Text {
id: texttitle
text: '<b>' + Utils.htmlEscaped(title) + '</b> by ' + from + "<br/>" + timestamp
leftPadding: 10
topPadding: 5
bottomPadding:5
color: windowItem.cwtch_dark_color
}
MouseArea {
anchors.fill: parent
onClicked: {
selected = !selected
bulletinView.currentIndex = index
}
RowLayout {
Button {
text: selected ? "-" : "+"
style: CwtchExpandingButton{}
}
Text {
id: texttitle
text: '<b>' + Utils.htmlEscaped(title) + '</b> by ' + from + "<br/>" + timestamp
leftPadding: 10
topPadding: 5
bottomPadding:5
color: windowItem.cwtch_dark_color
}
MouseArea {
anchors.fill: parent
onClicked: {
selected = !selected
bulletinView.currentIndex = index
}
}
}
}
}
Rectangle {
height: 1
color: windowItem.cwtch_color
anchors {
left: parent.left
right: parent.right
}
}
Rectangle {
height: 1
color: windowItem.cwtch_color
anchors {
left: parent.left
right: parent.right
}
}
Text {
id: textbody
visible: selected
text: Utils.htmlEscaped(body)
wrapMode: TextEdit.Wrap
leftPadding: 10
topPadding: 10
width: parent.width - 50
}
Text {
id: textbody
visible: selected
text: Utils.htmlEscaped(body)
wrapMode: TextEdit.Wrap
leftPadding: 10
topPadding: 10
width: parent.width - 50
}
Widgets.Button {
id: replybtn
visible: selected
text: "reply"
anchors.right: parent.right
anchors.rightMargin:10
onClicked: {
gcd.broadcast("ResetMessagePane")
theStack.pane = theStack.messagePane
gcd.loadMessagesPane(from)
overlayStack.overlay = overlayStack.chatOverlay
}
}
}
Widgets.Button {
id: replybtn
visible: selected
text: "reply"
anchors.right: parent.right
anchors.rightMargin:10
onClicked: {
gcd.broadcast("ResetMessagePane")
theStack.pane = theStack.messagePane
gcd.loadMessagesPane(from)
overlayStack.overlay = overlayStack.chatOverlay
}
}
}
}
}
focus: true
ListModel {
id: jsonModel4
}
}
}
focus: true
ListModel {
id: jsonModel4
}
}
}
GroupBox {
title: qsTr("new-bulletin-label")
Layout.fillWidth: true
GroupBox {
title: qsTr("new-bulletin-label")
Layout.fillWidth: true
RowLayout {
Layout.fillWidth: true
width: parent.width
ColumnLayout {
Layout.fillWidth: true
RowLayout {
Layout.fillWidth: true
width: parent.width
ColumnLayout {
Layout.fillWidth: true
Text {
//: Post a new Bulletin Post
text: qsTr("post-new-bulletin-label")
}
Text {
//: Post a new Bulletin Post
text: qsTr("post-new-bulletin-label")
}
TextField {
id: newposttitle
//: title place holder text
placeholderText: qsTr("title-placeholder")
Layout.fillWidth: true
style: CwtchTextFieldStyle{}
}
TextField {
id: newposttitle
//: title place holder text
placeholderText: qsTr("title-placeholder")
Layout.fillWidth: true
style: CwtchTextFieldStyle{}
}
TextArea {
id: newpostbody
Layout.fillWidth: true
style: CwtchTextAreaStyle{}
}
TextArea {
id: newpostbody
Layout.fillWidth: true
style: CwtchTextAreaStyle{}
}
Widgets.Button { // SEND MESSAGE BUTTON
id: btnSend
icon: "regular/paper-plane"
text: "post"
anchors.right: parent.right
anchors.rightMargin: 2
Widgets.Button { // SEND MESSAGE BUTTON
id: btnSend
icon: "regular/paper-plane"
text: "post"
anchors.right: parent.right
anchors.rightMargin: 2
property int nextMessageID: 1
property int nextMessageID: 1
onClicked: {
if (newposttitle.text != "" && newpostbody.text != "") {
var msg = JSON.stringify({"o":2, "t":newposttitle.text, "b":newpostbody.text})
gcd.sendMessage(msg, nextMessageID++)
}
newposttitle.text = ""
newpostbody.text = ""
}
}
}
}
onClicked: {
if (newposttitle.text != "" && newpostbody.text != "") {
var msg = JSON.stringify({"o":2, "t":newposttitle.text, "b":newpostbody.text})
gcd.sendMessage(msg, nextMessageID++)
}
newposttitle.text = ""
newpostbody.text = ""
}
}
}
}
}
}

View File

@ -10,7 +10,7 @@ import "../fonts/Twemoji.js" as T
import "../utils.js" as Utils
Item {
width: parent.width
width: parent.width
property bool loading
ListModel { // MESSAGE OBJECTS ARE STORED HERE ...
@ -26,7 +26,7 @@ Item {
model: messagesModel
spacing: 6
clip: true
ScrollBar.vertical: ScrollBar {}
ScrollBar.vertical: ScrollBar {}
maximumFlickVelocity: 1250
delegate: Widgets.Message {
@ -57,7 +57,7 @@ Item {
try {
msg = JSON.parse(message)
} catch (e) {
msg = {"o": 1, "d": "(legacy message type) " + message}
msg = {"o": 1, "d": "(legacy message type) " + message}
}
if (msg.o != 1) return
@ -90,7 +90,7 @@ Item {
try {
msg = JSON.parse(message)
} catch (e) {
msg = {"o": 1, "d": "(legacy message type) " + message}
msg = {"o": 1, "d": "(legacy message type) " + message}
}
if (msg.o != 1) return
@ -128,199 +128,199 @@ Item {
}
}
Widgets.EmojiDrawer {
id: emojiDrawer
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: rowDrawer.top
size: 24 * gcd.themeScale
Widgets.EmojiDrawer {
id: emojiDrawer
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: rowDrawer.top
size: 24 * gcd.themeScale
onPicked: function(shortcode) {
if (!txtMessage.enabled) return
txtMessage.insert(txtMessage.cursorPosition, ":" + shortcode + ":")
}
}
onPicked: function(shortcode) {
if (!txtMessage.enabled) return
txtMessage.insert(txtMessage.cursorPosition, ":" + shortcode + ":")
}
}
RowLayout { // THE BOTTOM DRAWER
id: rowDrawer
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.right: parent.right
RowLayout { // THE BOTTOM DRAWER
id: rowDrawer
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.right: parent.right
Rectangle { // MESSAGE ENTRY TEXTFIELD
id: rectMessage
Layout.fillWidth: true
Layout.minimumHeight: 40 * gcd.themeScale
Layout.maximumHeight: 40 * gcd.themeScale
color: txtMessage.isEnabled ? "#EDEDED" : "#CCCCCC"
border.color: "#AAAAAA"
radius: 10
Rectangle { // MESSAGE ENTRY TEXTFIELD
id: rectMessage
Layout.fillWidth: true
Layout.minimumHeight: 40 * gcd.themeScale
Layout.maximumHeight: 40 * gcd.themeScale
color: txtMessage.isEnabled ? "#EDEDED" : "#CCCCCC"
border.color: "#AAAAAA"
radius: 10
MouseArea {
anchors.fill: parent
onClicked: txtMessage.focus = true
}
MouseArea {
anchors.fill: parent
onClicked: txtMessage.focus = true
}
Flickable {
id: flkMessage
anchors.fill: parent//this does nothing! bug in qt
Layout.minimumWidth: parent.width
Layout.maximumWidth: parent.width
Layout.minimumHeight: rectMessage.height
Layout.maximumHeight: rectMessage.height
contentWidth: txtMessage.width
contentHeight: txtMessage.height
boundsBehavior: Flickable.StopAtBounds
clip:true
maximumFlickVelocity: 300
Flickable {
id: flkMessage
anchors.fill: parent//this does nothing! bug in qt
Layout.minimumWidth: parent.width
Layout.maximumWidth: parent.width
Layout.minimumHeight: rectMessage.height
Layout.maximumHeight: rectMessage.height
contentWidth: txtMessage.width
contentHeight: txtMessage.height
boundsBehavior: Flickable.StopAtBounds
clip:true
maximumFlickVelocity: 300
ScrollBar.vertical: ScrollBar{}
ScrollBar.vertical: ScrollBar{}
TextEdit {
id: txtMessage
font.pixelSize: 10 * gcd.themeScale
text: ""
padding: 6
wrapMode: TextEdit.Wrap
textFormat: Text.RichText
width: rectMessage.width
TextEdit {
id: txtMessage
font.pixelSize: 10 * gcd.themeScale
text: ""
padding: 6
wrapMode: TextEdit.Wrap
textFormat: Text.RichText
width: rectMessage.width
property bool skipOneUpdate: false
property int previousCursor
property bool skipOneUpdate: false
property int previousCursor
Keys.onReturnPressed: { // CTRL+ENTER = LINEBREAK
Keys.onReturnPressed: { // CTRL+ENTER = LINEBREAK
if ((event.modifiers & Qt.ControlModifier) && gcd.os != "android") {
txtMessage.insert(txtMessage.cursorPosition, "<br>")
} else if (event.modifiers == Qt.NoModifier) {
btnSend.clicked()
}
}
txtMessage.insert(txtMessage.cursorPosition, "<br>")
} else if (event.modifiers == Qt.NoModifier) {
btnSend.clicked()
}
}
// welcome to the emoji parser! it is horrifying code that needs to leave in <img src="[emoji]">
// while also stripping any other tag, including other images.
// TODO: this probably breaks if people actually do want to paste html
onTextChanged: {
// welcome to the emoji parser! it is horrifying code that needs to leave in <img src="[emoji]">
// while also stripping any other tag, including other images.
// TODO: this probably breaks if people actually do want to paste html
onTextChanged: {
if (gcd.os == "android") {
return
}
// we're taking advantage of TextEdit.getText()'s parsing capability, which means occasionally
// passing text into it to be filtered. this prevents recursive calls putting us into an
// infinite loop
if (skipOneUpdate) {
skipOneUpdate = false
return
}
// we're taking advantage of TextEdit.getText()'s parsing capability, which means occasionally
// passing text into it to be filtered. this prevents recursive calls putting us into an
// infinite loop
if (skipOneUpdate) {
skipOneUpdate = false
return
}
previousCursor = cursorPosition
//console.log("onTextChanged() at position " + previousCursor)
previousCursor = cursorPosition
//console.log("onTextChanged() at position " + previousCursor)
//console.log("1: " + txtMessage.getText(0, txtMessage.text.length))
//console.log("1: " + txtMessage.getText(0, txtMessage.text.length))
// convert <img> tags back to their emoji form
// Then parse out the rest of the HTML
var nt = restoreEmoji(txtMessage.text)
if (nt != txtMessage.text) {
skipOneUpdate = true
txtMessage.text = nt
}
// convert <img> tags back to their emoji form
// Then parse out the rest of the HTML
var nt = restoreEmoji(txtMessage.text)
if (nt != txtMessage.text) {
skipOneUpdate = true
txtMessage.text = nt
}
//console.log("2: " + txtMessage.getText(0, txtMessage.text.length))
var preserveSpaces = txtMessage.text.replace(/<br \/>/g,"[:newline:]");
if (preserveSpaces != txtMessage.text) {
skipOneUpdate = true
txtMessage.text = preserveSpaces
}
// strip all HTML tags
var theText = Utils.htmlEscaped(txtMessage.getText(0, txtMessage.text.length))
//console.log("3: " + theText)
//console.log("2: " + txtMessage.getText(0, txtMessage.text.length))
var preserveSpaces = txtMessage.text.replace(/<br \/>/g,"[:newline:]");
if (preserveSpaces != txtMessage.text) {
skipOneUpdate = true
txtMessage.text = preserveSpaces
}
// strip all HTML tags
var theText = Utils.htmlEscaped(txtMessage.getText(0, txtMessage.text.length))
//console.log("3: " + theText)
// convert emoji back to <img> tags
nt = parse(theText, 10)
//console.log("4: " + nt)
// convert emoji back to <img> tags
nt = parse(theText, 10)
//console.log("4: " + nt)
// preserve double spacing
nt = nt.replace(/\s\s/g, "&nbsp;&nbsp;");
nt = nt.replace(/\[\:newline\:\]/g, "<br/>");
// preserve double spacing
nt = nt.replace(/\s\s/g, "&nbsp;&nbsp;");
nt = nt.replace(/\[\:newline\:\]/g, "<br/>");
// then we actually put the updated text in
skipOneUpdate = true
txtMessage.text = nt
// then we actually put the updated text in
skipOneUpdate = true
txtMessage.text = nt
txtMessage.cursorPosition = previousCursor
txtMessage.cursorPosition = previousCursor
// autoscroll down only when the scrollbar is already all the way down
if (flkMessage.contentY + flkMessage.height >= flkMessage.contentHeight - txtMessage.height && flkMessage.contentHeight > flkMessage.height) {
flkMessage.contentY = flkMessage.contentHeight - flkMessage.height
}
}
}
}
}
// autoscroll down only when the scrollbar is already all the way down
if (flkMessage.contentY + flkMessage.height >= flkMessage.contentHeight - txtMessage.height && flkMessage.contentHeight > flkMessage.height) {
flkMessage.contentY = flkMessage.contentHeight - flkMessage.height
}
}
}
}
}
ColumnLayout {
id: colRight
spacing: 1
ColumnLayout {
id: colRight
spacing: 1
Widgets.Button { // SEND MESSAGE BUTTON
id: btnSend
icon: "regular/paper-plane"
text: "send"
Layout.minimumWidth: btnEmoji.width + btnAttach.width + 2
Layout.maximumWidth: btnEmoji.width + btnAttach.width + 2
anchors.right: parent.right
anchors.rightMargin: 2
Widgets.Button { // SEND MESSAGE BUTTON
id: btnSend
icon: "regular/paper-plane"
text: "send"
Layout.minimumWidth: btnEmoji.width + btnAttach.width + 2
Layout.maximumWidth: btnEmoji.width + btnAttach.width + 2
anchors.right: parent.right
anchors.rightMargin: 2
property int nextMessageID: 1
property int nextMessageID: 1
TextEdit {
id: txtHidden
visible: false
textFormat: Text.RichText
}
TextEdit {
id: txtHidden
visible: false
textFormat: Text.RichText
}
onClicked: {
if (txtMessage.text != "") {
txtHidden.text = restoreEmoji(txtMessage.text)
txtHidden.text = txtHidden.text.replace(/<br \/>/g,"[:newline:]");
var txt = txtHidden.text.trim()
if (txt.length > 0) {
var rawText = txtHidden.getText(0, txtHidden.text.length)
var msg = JSON.stringify({"o":1, "d":rawText.replace(/\[\:newline\:\]/g,"\n")})
gcd.sendMessage(msg, nextMessageID++)
}
}
txtMessage.text = ""
}
}
onClicked: {
if (txtMessage.text != "") {
txtHidden.text = restoreEmoji(txtMessage.text)
txtHidden.text = txtHidden.text.replace(/<br \/>/g,"[:newline:]");
var txt = txtHidden.text.trim()
if (txt.length > 0) {
var rawText = txtHidden.getText(0, txtHidden.text.length)
var msg = JSON.stringify({"o":1, "d":rawText.replace(/\[\:newline\:\]/g,"\n")})
gcd.sendMessage(msg, nextMessageID++)
}
}
txtMessage.text = ""
}
}
RowLayout {
spacing: 1
RowLayout {
spacing: 1
Widgets.Button { // EMOJI DRAWER BUTTON
id: btnEmoji
icon: "regular/smile"
anchors.right: btnAttach.left
anchors.rightMargin: 2
Widgets.Button { // EMOJI DRAWER BUTTON
id: btnEmoji
icon: "regular/smile"
anchors.right: btnAttach.left
anchors.rightMargin: 2
onClicked: emojiDrawer.visible ? emojiDrawer.slideclosed() : emojiDrawer.slideopen()
}
onClicked: emojiDrawer.visible ? emojiDrawer.slideclosed() : emojiDrawer.slideopen()
}
Widgets.Button {
id: btnAttach
icon: "solid/paperclip"
anchors.right: parent.right
anchors.rightMargin: 2
Widgets.Button {
id: btnAttach
icon: "solid/paperclip"
anchors.right: parent.right
anchors.rightMargin: 2
onClicked: {
gcd.popup("attachments not yet implemented, sorry")
}
}
}
}
}
onClicked: {
gcd.popup("attachments not yet implemented, sorry")
}
}
}
}
}
}

View File

@ -12,51 +12,51 @@ import "../utils.js" as Utils
import "../styles"
ColumnLayout {
Layout.fillWidth: true
width:parent.width
Layout.fillWidth: true
width:parent.width
Text {
Layout.fillWidth: true
}
Text {
Layout.fillWidth: true
}
TextField {
id: filter
TextField {
id: filter
placeholderText: "Search.."
placeholderText: "Search.."
style: CwtchTextFieldStyle{}
style: CwtchTextFieldStyle{}
anchors.left: parent.left
anchors.right: parent.right
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 10
anchors.margins: 10
onTextChanged: {
bulletinView.filter = text
if (bulletinView.model.get(bulletinView.currentIndex).title.indexOf(text) == -1) {
bulletinView.currentIndex = -1
}
}
}
onTextChanged: {
bulletinView.filter = text
if (bulletinView.model.get(bulletinView.currentIndex).title.indexOf(text) == -1) {
bulletinView.currentIndex = -1
}
}
}
Flickable { // THE MESSAGE LIST ITSELF
id: sv
clip: true
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
Layout.fillHeight: true
Layout.fillWidth: true
contentWidth: parent.width
contentHeight: parent.height
boundsBehavior: Flickable.StopAtBounds
maximumFlickVelocity: 800
Flickable { // THE MESSAGE LIST ITSELF
id: sv
clip: true
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
Layout.fillHeight: true
Layout.fillWidth: true
contentWidth: parent.width
contentHeight: parent.height
boundsBehavior: Flickable.StopAtBounds
maximumFlickVelocity: 800
Connections {
target: gcd
Connections {
target: gcd
onClearMessages: function() {
jsonModel4.clear()
}
onClearMessages: function() {
jsonModel4.clear()
}
onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts, ack, error) {
handler(handle, from, displayName, message, image, mid, fromMe, ts, ack, error)
@ -68,33 +68,33 @@ ColumnLayout {
function handler(handle, from, displayName, message, image, mid, fromMe, ts, ack, error) {
var msg
try {
msg = JSON.parse(message)
} catch (e) {
return
}
if (msg.o != 4) return
var msg
try {
msg = JSON.parse(message)
} catch (e) {
return
}
if (msg.o != 4) return
if (msg.t != undefined) {
jsonModel4.insert(0,{
"title":msg.t,
"selected":false,
"from": from,
"displayName": displayName,
"timestamp": ts,
"complete": false
})
}
if (msg.t != undefined) {
jsonModel4.insert(0,{
"title":msg.t,
"selected":false,
"from": from,
"displayName": displayName,
"timestamp": ts,
"complete": false
})
}
/*if(msg.c != undefined) {
jsonModel4.get(msg.c).complete = true
}
/*if(msg.c != undefined) {
jsonModel4.get(msg.c).complete = true
}
if (sv.contentY + sv.height >= sv.contentHeight - colMessages.height && sv.contentHeight > sv.height) {
sv.contentY = sv.contentHeight - sv.height
}*/
}
if (sv.contentY + sv.height >= sv.contentHeight - colMessages.height && sv.contentHeight > sv.height) {
sv.contentY = sv.contentHeight - sv.height
}*/
}
onUpdateContactStatus: function(_handle, _status, _loading) {
if (gcd.selectedConversation == _handle) {
@ -108,123 +108,123 @@ ColumnLayout {
}
}
}
}
ScrollBar.vertical: ScrollBar{
policy: ScrollBar.AlwaysOn
}
ScrollBar.vertical: ScrollBar{
policy: ScrollBar.AlwaysOn
}
ListView {
id: bulletinView
anchors.left: parent.left
anchors.leftMargin: 10
anchors.topMargin: 10
ListView {
id: bulletinView
anchors.left: parent.left
anchors.leftMargin: 10
anchors.topMargin: 10
width: parent.width - 50
height: parent.height - 20
orientation: Qt.Vertical
spacing: 10
model: jsonModel4
property string filter: ""
delegate:
width: parent.width - 50
height: parent.height - 20
orientation: Qt.Vertical
spacing: 10
model: jsonModel4
property string filter: ""
delegate:
Item {
width: parent.width
height: title.indexOf(bulletinView.filter) >= 0 ? texttitle.height : 0
visible: title.indexOf(bulletinView.filter) >= 0
Item {
width: parent.width
height: title.indexOf(bulletinView.filter) >= 0 ? texttitle.height : 0
visible: title.indexOf(bulletinView.filter) >= 0
Column {
width: parent.width
Column {
width: parent.width
RowLayout {
CheckBox {
checked: complete
onClicked: {
var msg = JSON.stringify({"o":4, "c":index})
gcd.sendMessage(msg, btnSend.nextMessageID++)
}
}
RowLayout {
CheckBox {
checked: complete
onClicked: {
var msg = JSON.stringify({"o":4, "c":index})
gcd.sendMessage(msg, btnSend.nextMessageID++)
}
}
RowLayout {
Text {
id: texttitle
text: '<b>' + Utils.htmlEscaped(title) + '</b> by ' + from + "<br/>" + timestamp
leftPadding: 10
topPadding: 5
bottomPadding:5
color: windowItem.cwtch_dark_color
}
}
}
RowLayout {
Text {
id: texttitle
text: '<b>' + Utils.htmlEscaped(title) + '</b> by ' + from + "<br/>" + timestamp
leftPadding: 10
topPadding: 5
bottomPadding:5
color: windowItem.cwtch_dark_color
}
}
}
Rectangle {
height: 1
color: windowItem.cwtch_color
anchors {
left: parent.left
right: parent.right
}
}
Rectangle {
height: 1
color: windowItem.cwtch_color
anchors {
left: parent.left
right: parent.right
}
}
}
}
}
}
focus: true
ListModel {
id: jsonModel4
}
}
}
focus: true
ListModel {
id: jsonModel4
}
}
}
GroupBox {
//: Add a New List Item
title: qsTr("add-list-item")
Layout.fillWidth: true
GroupBox {
//: Add a New List Item
title: qsTr("add-list-item")
Layout.fillWidth: true
RowLayout {
Layout.fillWidth: true
width: parent.width
ColumnLayout {
Layout.fillWidth: true
RowLayout {
Layout.fillWidth: true
width: parent.width
ColumnLayout {
Layout.fillWidth: true
Text {
//: Add a new item to the list
text: qsTr("add-new-item")
}
Text {
//: Add a new item to the list
text: qsTr("add-new-item")
}
TextField {
id: newposttitle
//: Todo... placeholder text
placeholderText: qsTr("todo-placeholder")
Layout.fillWidth: true
style: CwtchTextFieldStyle{}
}
TextField {
id: newposttitle
//: Todo... placeholder text
placeholderText: qsTr("todo-placeholder")
Layout.fillWidth: true
style: CwtchTextFieldStyle{}
}
Widgets.Button { // SEND MESSAGE BUTTON
id: btnSend
icon: "regular/paper-plane"
text: "add"
anchors.right: parent.right
anchors.rightMargin: 2
Widgets.Button { // SEND MESSAGE BUTTON
id: btnSend
icon: "regular/paper-plane"
text: "add"
anchors.right: parent.right
anchors.rightMargin: 2
property int nextMessageID: 1
property int nextMessageID: 1
onClicked: {
if (newposttitle.text != "") {
var msg = JSON.stringify({"o":4, "t":newposttitle.text})
gcd.sendMessage(msg, nextMessageID++)
}
newposttitle.text = ""
}
}
}
}
onClicked: {
if (newposttitle.text != "") {
var msg = JSON.stringify({"o":4, "t":newposttitle.text})
gcd.sendMessage(msg, nextMessageID++)
}
newposttitle.text = ""
}
}
}
}
}
}

View File

@ -12,45 +12,45 @@ 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")
}
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
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
}
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AlwaysOn
}
ColumnLayout {
id: colContacts
width: sv.width
spacing: 0
id: colContacts
width: sv.width
spacing: 0
Connections { // ADD/REMOVE CONTACT ENTRIES
target: gcd
Connections { // ADD/REMOVE CONTACT ENTRIES
target: gcd
onClearMessages: function() {
contactsModel.clear()
}
onClearMessages: function() {
contactsModel.clear()
}
onAppendMessage: function(handle, from, displayName, message, image, mid, fromMe, ts, ack, error) {
handler(handle, from, displayName, message, image, mid, fromMe, ts, ack, error)
@ -63,51 +63,51 @@ ColumnLayout {
function handler(handle, from, displayName, message, image, mid, fromMe, ts, ack, error) {
var msg
try {
msg = JSON.parse(message)
} catch (e) {
return
}
try {
msg = JSON.parse(message)
} catch (e) {
return
}
if (from == "me") {
return
}
if (from == "me") {
return
}
for(var i = 0; i<contactsModel.count;i++){
if(contactsModel.get(i)["_handle"] == handle) {
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,
})
}
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
}
ListModel { // CONTACT OBJECTS ARE STORED HERE ...
id: contactsModel
}
Repeater {
model: contactsModel // ... AND DISPLAYED HERE
delegate: ContactRow {
handle: _handle
displayName: _displayName
image: _image
blocked: false
}
}
}
}
Repeater {
model: contactsModel // ... AND DISPLAYED HERE
delegate: ContactRow {
handle: _handle
displayName: _displayName
image: _image
blocked: false
}
}
}
}
}

View File

@ -11,64 +11,64 @@ import "../styles"
ColumnLayout { // settingsPane
id: root
anchors.fill: parent
anchors.fill: parent
Widgets.StackToolbar {
id: stb
text: qsTr("create-group-title")
aux.visible: false
membership.visible: false
}
Widgets.StackToolbar {
id: stb
text: qsTr("create-group-title")
aux.visible: false
membership.visible: false
}
Flickable {
anchors.top: stb.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
boundsBehavior: Flickable.StopAtBounds
clip:true
contentWidth: tehcol.width
contentHeight: tehcol.height
anchors.top: stb.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
boundsBehavior: Flickable.StopAtBounds
clip:true
contentWidth: tehcol.width
contentHeight: tehcol.height
Column {
id: tehcol
leftPadding: 10
spacing: 5
width: root.width
Column {
id: tehcol
leftPadding: 10
spacing: 5
width: root.width
Widgets.ScalingLabel {
//: Server label
text: qsTr("server-label") + ":"
}
Widgets.ScalingLabel {
//: Server label
text: qsTr("server-label") + ":"
}
TextField {
id: txtServer
style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
text: "2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd"
}
TextField {
id: txtServer
style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
text: "2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd"
}
Widgets.ScalingLabel{
//: Group name label
text: qsTr("group-name-label") + ":"
}
Widgets.ScalingLabel{
//: Group name label
text: qsTr("group-name-label") + ":"
}
TextField {
id: txtGroupName
style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
//: default suggested group name
text: qsTr("default-group-name")
}
TextField {
id: txtGroupName
style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
//: default suggested group name
text: qsTr("default-group-name")
}
Widgets.Button {
//: create group button
text: qsTr("create-group-btn")
Widgets.Button {
//: create group button
text: qsTr("create-group-btn")
onClicked: {
gcd.createGroup(txtServer.text, txtGroupName.text)
}
}
onClicked: {
gcd.createGroup(txtServer.text, txtGroupName.text)
}
}
}//end of column with padding
}//end of column with padding
}//end of flickable
}
}

View File

@ -11,137 +11,137 @@ import "../styles"
import "../utils.js" as Utils
ColumnLayout { // groupSettingsPane
id: gsp
anchors.fill: parent
property string groupID
id: gsp
anchors.fill: parent
property string groupID
property variant addrbook
Widgets.StackToolbar {
id: toolbar
aux.visible: false
back.onClicked: theStack.pane = theStack.messagePane
}
Widgets.StackToolbar {
id: toolbar
aux.visible: false
back.onClicked: theStack.pane = theStack.messagePane
}
Flickable {
anchors.top: toolbar.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
boundsBehavior: Flickable.StopAtBounds
clip:true
contentWidth: tehcol.width
contentHeight: tehcol.height
anchors.top: toolbar.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
boundsBehavior: Flickable.StopAtBounds
clip:true
contentWidth: tehcol.width
contentHeight: tehcol.height
Column {
id: tehcol
width: gsp.width
leftPadding: 10
spacing: 5
Column {
id: tehcol
width: gsp.width
leftPadding: 10
spacing: 5
Widgets.ScalingLabel {
text: qsTr("server-label") + ":"
}
Widgets.ScalingLabel {
text: qsTr("server-label") + ":"
}
TextField {
id: txtServer
style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
readOnly: true
}
TextField {
id: txtServer
style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
readOnly: true
}
Widgets.Button {
icon: "regular/clipboard"
text: qsTr("copy-btn")
Widgets.Button {
icon: "regular/clipboard"
text: qsTr("copy-btn")
onClicked: {
gcd.popup("copied-clipboard-notification")
txtServer.selectAll()
txtServer.copy()
}
}
onClicked: {
gcd.popup("copied-clipboard-notification")
txtServer.selectAll()
txtServer.copy()
}
}
Widgets.ScalingLabel {
text: qsTr("invitation-label") + ":"
}
Widgets.ScalingLabel {
text: qsTr("invitation-label") + ":"
}
TextField {
id: txtInvitation
style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
readOnly: true
}
TextField {
id: txtInvitation
style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
readOnly: true
}
Widgets.Button {
icon: "regular/clipboard"
text: qsTr("copy-btn")
Widgets.Button {
icon: "regular/clipboard"
text: qsTr("copy-btn")
onClicked: {
gcd.popup("copied-clipboard-notification")
txtInvitation.selectAll()
txtInvitation.copy()
}
}
onClicked: {
gcd.popup("copied-clipboard-notification")
txtInvitation.selectAll()
txtInvitation.copy()
}
}
Widgets.ScalingLabel{
text: qsTr("group-name-label") + ":"
}
Widgets.ScalingLabel{
text: qsTr("group-name-label") + ":"
}
TextField {
id: txtGroupName
style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
}
TextField {
id: txtGroupName
style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
}
Widgets.Button {
text: qsTr("save-btn")
Widgets.Button {
text: qsTr("save-btn")
onClicked: {
gcd.saveGroupSettings(groupID, txtGroupName.text)
theStack.title = txtGroupName.text
theStack.pane = theStack.messagePane
}
}
onClicked: {
gcd.saveGroupSettings(groupID, txtGroupName.text)
theStack.title = txtGroupName.text
theStack.pane = theStack.messagePane
}
}
//: Invite someone to the group
Widgets.ScalingLabel { text: qsTr("invite-to-group-label") }
//: Invite someone to the group
Widgets.ScalingLabel { text: qsTr("invite-to-group-label") }
ComboBox {
id: cbInvite
//popup.font.pixelSize: 12
width: 200
//font.pixelSize: 20
style: CwtchComboBoxStyle{}
}
ComboBox {
id: cbInvite
//popup.font.pixelSize: 12
width: 200
//font.pixelSize: 20
style: CwtchComboBoxStyle{}
}
Widgets.Button {
text: qsTr("invite-btn")
Widgets.Button {
text: qsTr("invite-btn")
onClicked: {
gcd.inviteToGroup(addrbook[cbInvite.currentIndex], groupID)
}
}
onClicked: {
gcd.inviteToGroup(addrbook[cbInvite.currentIndex], groupID)
}
}
Widgets.Button {
icon: "regular/trash-alt"
text: qsTr("delete-btn")
Widgets.Button {
icon: "regular/trash-alt"
text: qsTr("delete-btn")
onClicked: {
gcd.leaveGroup(groupID)
theStack.pane = theStack.emptyPane
}
}
onClicked: {
gcd.leaveGroup(groupID)
theStack.pane = theStack.emptyPane
}
}
}//end of column with padding
}//end of column with padding
}//end of flickable
Connections {
target: gcd
Connections {
target: gcd
onSupplyGroupSettings: function(gid, name, server, invite, accepted, addrbooknames, addrbookaddrs) {
gsp.groupID = gid
toolbar.text = name
txtGroupName.text = name
txtServer.text = server
txtInvitation.text = invite
cbInvite.model = addrbooknames.map(function(e){return Utils.htmlEscaped(e)})
addrbook = addrbookaddrs
}
}
}
onSupplyGroupSettings: function(gid, name, server, invite, accepted, addrbooknames, addrbookaddrs) {
gsp.groupID = gid
toolbar.text = name
txtGroupName.text = name
txtServer.text = server
txtInvitation.text = invite
cbInvite.model = addrbooknames.map(function(e){return Utils.htmlEscaped(e)})
addrbook = addrbookaddrs
}
}
}

View File

@ -8,68 +8,68 @@ import "../widgets" as Widgets
import "../overlays"
ColumnLayout {
Layout.fillWidth: true
property alias title: toolbar.text
id: overlay
property string name
property bool accepted
property bool inGroup
Layout.fillWidth: true
property alias title: toolbar.text
id: overlay
property string name
property bool accepted
property bool inGroup
Widgets.StackToolbar {
id: toolbar
Widgets.StackToolbar {
id: toolbar
membership.visible: gcd.selectedConversation.length == 32
membership.visible: gcd.selectedConversation.length == 32
membership.onClicked: overlayStack.overlay = overlayStack.membershipOverlay
membership.onClicked: overlayStack.overlay = overlayStack.membershipOverlay
aux.onClicked: {
if (gcd.selectedConversation.length == 32) {
theStack.pane = theStack.groupProfilePane
gcd.requestGroupSettings(gcd.selectedConversation)
} else {
theStack.pane = theStack.userProfilePane
gcd.requestPeerSettings()
}
}
back.visible: true
}
RowLayout {
visible:!overlay.accepted && (gcd.selectedConversation.length == 32)
Text {
//: Do you want to accept the invitation to $GROUP
text: qsTr("accept-group-invite-label") + " " + overlay.name + "?"
}
Widgets.Button {
//: Accept group invite button
text: qsTr("accept-group-btn")
icon: "regular/heart"
onClicked: {
gcd.acceptGroup(gcd.selectedConversation)
gcd.requestGroupSettings(gcd.selectedConversation)
}
}
Widgets.Button {
//: Reject Group invite button
text: qsTr("reject-group-btn")
icon: "regular/trash-alt"
onClicked: {
gcd.leaveGroup(gcd.selectedConversation)
theStack.pane = theStack.emptyPane
}
}
}
aux.onClicked: {
if (gcd.selectedConversation.length == 32) {
theStack.pane = theStack.groupProfilePane
gcd.requestGroupSettings(gcd.selectedConversation)
} else {
theStack.pane = theStack.userProfilePane
gcd.requestPeerSettings()
}
}
back.visible: true
}
RowLayout {
id: switcher
visible:!overlay.accepted && (gcd.selectedConversation.length == 32)
Widgets.Button {
Text {
//: Do you want to accept the invitation to $GROUP
text: qsTr("accept-group-invite-label") + " " + overlay.name + "?"
}
Widgets.Button {
//: Accept group invite button
text: qsTr("accept-group-btn")
icon: "regular/heart"
onClicked: {
gcd.acceptGroup(gcd.selectedConversation)
gcd.requestGroupSettings(gcd.selectedConversation)
}
}
Widgets.Button {
//: Reject Group invite button
text: qsTr("reject-group-btn")
icon: "regular/trash-alt"
onClicked: {
gcd.leaveGroup(gcd.selectedConversation)
theStack.pane = theStack.emptyPane
}
}
}
RowLayout {
id: switcher
Widgets.Button {
text: qsTr("chat-btn")
@ -124,18 +124,18 @@ ColumnLayout {
}
MembershipOverlay { //3
Layout.maximumHeight: overlayStack.height
Layout.maximumWidth: overlayStack.width
Layout.maximumHeight: overlayStack.height
Layout.maximumWidth: overlayStack.width
}
}
Connections {
target: gcd
onResetMessagePane: function() {
overlayStack.overlay = overlayStack.chatOverlay
overlay.inGroup = false
}
onResetMessagePane: function() {
overlayStack.overlay = overlayStack.chatOverlay
overlay.inGroup = false
}
onSupplyGroupSettings: function(gid, name, server, invite, accepted, addrbooknames, addrbookaddrs) {
overlay.name = name
@ -143,4 +143,4 @@ ColumnLayout {
overlay.inGroup = true
}
}
}
}

View File

@ -12,114 +12,114 @@ import "../theme"
ColumnLayout { // peerSettingsPane
id: root
anchors.fill: parent
property bool blocked
anchors.fill: parent
property bool blocked
Widgets.StackToolbar {
id: toolbar
aux.visible: false
Widgets.StackToolbar {
id: toolbar
aux.visible: false
back.onClicked: theStack.pane = theStack.messagePane
}
Flickable {
anchors.top: toolbar.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
boundsBehavior: Flickable.StopAtBounds
clip:true
contentWidth: tehcol.width
contentHeight: tehcol.height
Column {
id: tehcol
width: root.width
leftPadding: 10
padding:10
spacing: 5
Widgets.EllipsisLabel {
color: Theme.mainTextColor
text: qsTr("address-label")
font.styleName: "ExtraBold"
font.pointSize: 15 * gcd.themeScale
}
Widgets.ButtonTextField {
id: txtOnion
//style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
readOnly: true
button_text: qsTr("copy-btn")
onClicked: {
//: notification: copied to clipboard
gcd.popup(qsTr("copied-to-clipboard-notification"))
txtOnion.selectAll()
txtOnion.copy()
}
}
Widgets.EllipsisLabel {
color: Theme.mainTextColor
text: qsTr("display-name-label")
font.styleName: "ExtraBold"
font.pointSize: 15 * gcd.themeScale
}
Widgets.ButtonTextField {
id: txtDisplayName
button_text: qsTr("save-btn")
onClicked: {
gcd.savePeerSettings(txtOnion.text, txtDisplayName.text)
theStack.title = txtDisplayName.text
theStack.pane = theStack.messagePane
}
}
Widgets.Button {
icon: "solid/hand-paper"
text: root.blocked ? qsTr("unblock-btn") : qsTr("block-btn")
onClicked: {
if (root.blocked) {
gcd.unblockPeer(txtOnion.text)
} else {
gcd.blockPeer(txtOnion.text)
}
root.blocked = !root.blocked
}
back.onClicked: theStack.pane = theStack.messagePane
}
Widgets.Button {
icon: "regular/trash-alt"
text: qsTr("delete-btn")
Flickable {
anchors.top: toolbar.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
boundsBehavior: Flickable.StopAtBounds
clip:true
contentWidth: tehcol.width
contentHeight: tehcol.height
onClicked: {
gcd.deleteContact(txtOnion.text)
theStack.pane = theStack.emptyPane
}
}
Column {
id: tehcol
width: root.width
leftPadding: 10
padding:10
spacing: 5
}//end of column with padding
Widgets.EllipsisLabel {
color: Theme.mainTextColor
text: qsTr("address-label")
font.styleName: "ExtraBold"
font.pointSize: 15 * gcd.themeScale
}
Widgets.ButtonTextField {
id: txtOnion
//style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
readOnly: true
button_text: qsTr("copy-btn")
onClicked: {
//: notification: copied to clipboard
gcd.popup(qsTr("copied-to-clipboard-notification"))
txtOnion.selectAll()
txtOnion.copy()
}
}
Widgets.EllipsisLabel {
color: Theme.mainTextColor
text: qsTr("display-name-label")
font.styleName: "ExtraBold"
font.pointSize: 15 * gcd.themeScale
}
Widgets.ButtonTextField {
id: txtDisplayName
button_text: qsTr("save-btn")
onClicked: {
gcd.savePeerSettings(txtOnion.text, txtDisplayName.text)
theStack.title = txtDisplayName.text
theStack.pane = theStack.messagePane
}
}
Widgets.Button {
icon: "solid/hand-paper"
text: root.blocked ? qsTr("unblock-btn") : qsTr("block-btn")
onClicked: {
if (root.blocked) {
gcd.unblockPeer(txtOnion.text)
} else {
gcd.blockPeer(txtOnion.text)
}
root.blocked = !root.blocked
}
}
Widgets.Button {
icon: "regular/trash-alt"
text: qsTr("delete-btn")
onClicked: {
gcd.deleteContact(txtOnion.text)
theStack.pane = theStack.emptyPane
}
}
}//end of column with padding
}//end of flickable
Connections {
target: gcd
Connections {
target: gcd
onSupplyPeerSettings: function(onion, nick, blocked) {
toolbar.text = nick
txtOnion.text = onion
txtDisplayName.text = nick
root.blocked = blocked
}
}
onSupplyPeerSettings: function(onion, nick, blocked) {
toolbar.text = nick
txtOnion.text = onion
txtDisplayName.text = nick
root.blocked = blocked
}
}
}
}

View File

@ -11,7 +11,7 @@ import "../widgets" as Widgets
ColumnLayout { // Add Profile Pane
id: profileAddEditPane
anchors.fill: parent
anchors.fill: parent
property string mode // edit or add
property string onion
@ -19,16 +19,16 @@ ColumnLayout { // Add Profile Pane
property bool deleting
property bool changingPassword
Widgets.StackToolbar {
id: stb
text: mode == "add" ? qsTr("add-profile-title") : qsTr("edit-profile-title")
aux.visible: false
membership.visible: false
stack: "management"
}
Widgets.StackToolbar {
id: stb
text: mode == "add" ? qsTr("add-profile-title") : qsTr("edit-profile-title")
aux.visible: false
membership.visible: false
stack: "management"
}
function reset() {
mode = "add"
function reset() {
mode = "add"
txtProfileName.text = qsTr("default-profile-name")
changingPassword = false
txtPassword1.text = ""
@ -42,17 +42,17 @@ ColumnLayout { // Add Profile Pane
confirmDeleteTxt.text = ""
radioUsePassword.checked = true
passwordChangeErrorLabel.visible = false
}
}
function load(userOnion, name, userTag) {
reset()
function load(userOnion, name, userTag) {
reset()
mode = "edit"
tag = userTag
onion = userOnion
txtPassword1.text = ""
mode = "edit"
tag = userTag
onion = userOnion
txtPassword1.text = ""
txtPassword2.text = ""
onionLabel.text = onion
onionLabel.text = onion
txtProfileName.text = name
if (tag == "v1-defaultPassword" || tag == "v1-default-password") {
@ -64,240 +64,240 @@ ColumnLayout { // Add Profile Pane
Flickable {
anchors.top: stb.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
boundsBehavior: Flickable.StopAtBounds
clip:true
contentWidth: tehcol.width
contentHeight: tehcol.height
anchors.top: stb.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
boundsBehavior: Flickable.StopAtBounds
clip:true
contentWidth: tehcol.width
contentHeight: tehcol.height
Column {
id: tehcol
leftPadding: 10
spacing: 5
width: profileAddEditPane.width
Column {
id: tehcol
leftPadding: 10
spacing: 5
width: profileAddEditPane.width
Widgets.ScalingLabel {
//: Onion
text: qsTr("profile-onion-label") + ":"
visible: mode == "edit"
}
Widgets.ScalingLabel {
id: onionLabel
visible: mode == "edit"
}
Widgets.ScalingLabel {
//: Display name
text: qsTr("profile-name") + ":"
}
Widgets.TextField {
id: txtProfileName
Layout.fillWidth: true
//style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
//: default suggested profile name
text: qsTr("default-profile-name")
}
RowLayout {
//id: radioButtons
Widgets.RadioButton {
id: radioUsePassword
checked: true
//: Password
text: qsTr("radio-use-password")
visible: mode == "add" || tag == "v1-defaultPassword"
onClicked: {
changingPassword = true
}
}
Widgets.RadioButton {
id: radioNoPassword
//: Unencrypted (No password)
text: qsTr("radio-no-password")
visible: mode == "add" || tag == "v1-defaultPassword"
onClicked: {
changingPassword = true
Widgets.ScalingLabel {
//: Onion
text: qsTr("profile-onion-label") + ":"
visible: mode == "edit"
}
}
}
Widgets.ScalingLabel {
id: noPasswordLabel
//: Not using a password on this account means that all data stored locally will not be encrypted
text: qsTr("no-password-warning")
visible: radioNoPassword.checked
}
Widgets.ScalingLabel {
id: onionLabel
visible: mode == "edit"
}
Widgets.ScalingLabel {
id: currentPasswordLabel
//: Current Password
text: qsTr("current-password-label") + ":"
visible: radioUsePassword.checked && mode == "edit" && tag != "v1-defaultPassword"
}
Widgets.ScalingLabel {
//: Display name
text: qsTr("profile-name") + ":"
}
Widgets.TextField {
id: txtCurrentPassword
Layout.fillWidth: true
echoMode: TextInput.Password
visible: radioUsePassword.checked && mode == "edit" && tag != "v1-defaultPassword"
}
Widgets.ScalingLabel {
id: passwordLabel
//: Password
text: qsTr("password1-label") + ":"
visible: radioUsePassword.checked
}
Widgets.TextField {
id: txtPassword1
Layout.fillWidth: true
//style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
echoMode: TextInput.Password
visible: radioUsePassword.checked
onTextEdited: {
changingPassword = true
}
}
Widgets.TextField {
id: txtProfileName
Layout.fillWidth: true
//style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
//: default suggested profile name
text: qsTr("default-profile-name")
Widgets.ScalingLabel {
id: passwordReLabel
//: Reenter password
text: qsTr("password2-label") + ":"
visible: radioUsePassword.checked
}
}
Widgets.TextField {
id: txtPassword2
Layout.fillWidth: true
//style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
echoMode: TextInput.Password
visible: radioUsePassword.checked
}
RowLayout {
//id: radioButtons
Widgets.Button { // ADD or SAVE button
//: Create Profile || Save Profile
text: mode == "add" ? qsTr("create-profile-btn") : qsTr("save-profile-btn")
onClicked: {
if (mode == "add") {
if (txtPassword1.text != txtPassword2.text) {
passwordErrorLabel.visible = true
} else {
gcd.createProfile(txtProfileName.text, radioNoPassword.checked, txtPassword1.text)
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
Widgets.RadioButton {
id: radioUsePassword
checked: true
//: Password
text: qsTr("radio-use-password")
visible: mode == "add" || tag == "v1-defaultPassword"
onClicked: {
changingPassword = true
}
}
} else {
gcd.updateNick(onion, txtProfileName.text)
if (changingPassword) {
if (txtPassword1.text != txtPassword2.text) {
passwordErrorLabel.visible = true
} else {
gcd.changePassword(onion, txtCurrentPassword.text, txtPassword1.text, radioNoPassword.checked)
}
} else {
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
}
}
}
}
Widgets.ScalingLabel {
id: passwordErrorLabel
//: Passwords do not match
text: qsTr("password-error-match")
visible: false
color: "red"
}
Widgets.ScalingLabel {
id: passwordChangeErrorLabel
//: Error changing password: Supplied password rejected
text: qsTr("password-change-error")
visible: false
color: "red"
}
// ***** Delete button and confirm flow *****
Widgets.Button {
//: Delete Profile
text: qsTr("delete-profile-btn")
icon: "regular/trash-alt"
visible: mode == "edit"
onClicked: {
deleting = true
}
}
Widgets.ScalingLabel {
id: deleteConfirmLabel
//: Type DELETE to confirm
text: qsTr("delete-confirm-label")+ ":"
visible: deleting
}
Widgets.TextField {
id: confirmDeleteTxt
Layout.fillWidth: true
//style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
visible: deleting
}
Widgets.Button {
id: confirmDeleteBtn
icon: "regular/trash-alt"
//: Really Delete Profile
text: qsTr("delete-profile-confirm-btn")
color: "red"
visible: deleting
onClicked: {
//: DELETE
if (confirmDeleteTxt.text == qsTr("delete-confirm-text")) {
deleteConfirmLabel.color = "black"
gcd.deleteProfile(onion)
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
} else {
deleteConfirmLabel.color = "red"
Widgets.RadioButton {
id: radioNoPassword
//: Unencrypted (No password)
text: qsTr("radio-no-password")
visible: mode == "add" || tag == "v1-defaultPassword"
onClicked: {
changingPassword = true
}
}
}
}
}
Widgets.ScalingLabel {
id: noPasswordLabel
//: Not using a password on this account means that all data stored locally will not be encrypted
text: qsTr("no-password-warning")
visible: radioNoPassword.checked
}
Widgets.ScalingLabel {
id: currentPasswordLabel
//: Current Password
text: qsTr("current-password-label") + ":"
visible: radioUsePassword.checked && mode == "edit" && tag != "v1-defaultPassword"
}
Widgets.TextField {
id: txtCurrentPassword
Layout.fillWidth: true
echoMode: TextInput.Password
visible: radioUsePassword.checked && mode == "edit" && tag != "v1-defaultPassword"
}
Widgets.ScalingLabel {
id: passwordLabel
//: Password
text: qsTr("password1-label") + ":"
visible: radioUsePassword.checked
}
Widgets.TextField {
id: txtPassword1
Layout.fillWidth: true
//style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
echoMode: TextInput.Password
visible: radioUsePassword.checked
onTextEdited: {
changingPassword = true
}
}
}//end of column with padding
Widgets.ScalingLabel {
id: passwordReLabel
//: Reenter password
text: qsTr("password2-label") + ":"
visible: radioUsePassword.checked
}
Widgets.TextField {
id: txtPassword2
Layout.fillWidth: true
//style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
echoMode: TextInput.Password
visible: radioUsePassword.checked
}
Widgets.Button { // ADD or SAVE button
//: Create Profile || Save Profile
text: mode == "add" ? qsTr("create-profile-btn") : qsTr("save-profile-btn")
onClicked: {
if (mode == "add") {
if (txtPassword1.text != txtPassword2.text) {
passwordErrorLabel.visible = true
} else {
gcd.createProfile(txtProfileName.text, radioNoPassword.checked, txtPassword1.text)
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
}
} else {
gcd.updateNick(onion, txtProfileName.text)
if (changingPassword) {
if (txtPassword1.text != txtPassword2.text) {
passwordErrorLabel.visible = true
} else {
gcd.changePassword(onion, txtCurrentPassword.text, txtPassword1.text, radioNoPassword.checked)
}
} else {
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
}
}
}
}
Widgets.ScalingLabel {
id: passwordErrorLabel
//: Passwords do not match
text: qsTr("password-error-match")
visible: false
color: "red"
}
Widgets.ScalingLabel {
id: passwordChangeErrorLabel
//: Error changing password: Supplied password rejected
text: qsTr("password-change-error")
visible: false
color: "red"
}
// ***** Delete button and confirm flow *****
Widgets.Button {
//: Delete Profile
text: qsTr("delete-profile-btn")
icon: "regular/trash-alt"
visible: mode == "edit"
onClicked: {
deleting = true
}
}
Widgets.ScalingLabel {
id: deleteConfirmLabel
//: Type DELETE to confirm
text: qsTr("delete-confirm-label")+ ":"
visible: deleting
}
Widgets.TextField {
id: confirmDeleteTxt
Layout.fillWidth: true
//style: CwtchTextFieldStyle{ width: tehcol.width * 0.8 }
visible: deleting
}
Widgets.Button {
id: confirmDeleteBtn
icon: "regular/trash-alt"
//: Really Delete Profile
text: qsTr("delete-profile-confirm-btn")
color: "red"
visible: deleting
onClicked: {
//: DELETE
if (confirmDeleteTxt.text == qsTr("delete-confirm-text")) {
deleteConfirmLabel.color = "black"
gcd.deleteProfile(onion)
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
} else {
deleteConfirmLabel.color = "red"
}
}
}
}//end of column with padding
}//end of flickable
Connections { // UPDATE UNREAD MESSAGES COUNTER
target: gcd
target: gcd
onChangePasswordResponse: function(error) {
if (!error) {
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
} else {
passwordChangeErrorLabel.visible = true
}
}
onChangePasswordResponse: function(error) {
if (!error) {
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
} else {
passwordChangeErrorLabel.visible = true
}
}
}
}
}

View File

@ -30,7 +30,7 @@ ColumnLayout {
TextField {
id: txtPassword
anchors.horizontalCenter: parent.horizontalCenter
style: CwtchTextFieldStyle{ width: thecol.width * 0.8 }
style: CwtchTextFieldStyle{ width: thecol.width * 0.8 }
echoMode: TextInput.Password
onAccepted: button.clicked()
}
@ -60,26 +60,26 @@ ColumnLayout {
}
Connections { // ADD/REMOVE CONTACT ENTRIES
target: gcd
target: gcd
onErrorLoaded0: function() {
error.visible = true
}
onErrorLoaded0: function() {
error.visible = true
}
}
Rectangle { // THE LEFT PANE WITH TOOLS AND CONTACTS
color: Theme.backgroundMainColor
width: thecol.width
color: Theme.backgroundMainColor
width: thecol.width
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: Layout.maximumWidth
//Layout.maximumWidth: theStack.pane == theStack.emptyPane ? parent.width : 450
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: Layout.maximumWidth
//Layout.maximumWidth: theStack.pane == theStack.emptyPane ? parent.width : 450
Widgets.ProfileList {
Widgets.ProfileList {
anchors.fill: parent
}
}
}

View File

@ -12,125 +12,125 @@ import "../widgets/controls"
ColumnLayout { // settingsPane
id: root
anchors.fill: parent
anchors.fill: parent
StackToolbar {
id: stb
StackToolbar {
id: stb
//: Cwtch Settings title
text: qsTr("cwtch-settings-title")
aux.visible: false
membership.visible: false
}
text: qsTr("cwtch-settings-title")
aux.visible: false
membership.visible: false
}
Flickable {
anchors.top: stb.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
boundsBehavior: Flickable.StopAtBounds
clip:true
contentWidth: tehcol.width
contentHeight: tehcol.height
anchors.top: stb.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
boundsBehavior: Flickable.StopAtBounds
clip:true
contentWidth: tehcol.width
contentHeight: tehcol.height
Column {
id: tehcol
leftPadding: 10
spacing: 5
width: root.width
Column {
id: tehcol
leftPadding: 10
spacing: 5
width: root.width
ScalingLabel {
width: parent.width
wrapMode: TextEdit.Wrap
//: Version: %1 Built on: %2
text: qsTr("version %1 builddate %2").arg(gcd.version).arg(gcd.buildDate)
}
ScalingLabel {
width: parent.width
wrapMode: TextEdit.Wrap
//: Version: %1 Built on: %2
text: qsTr("version %1 builddate %2").arg(gcd.version).arg(gcd.buildDate)
}
ScalingLabel {
width: parent.width
wrapMode: TextEdit.Wrap
//: Interface zoom (mostly affects text and button sizes)
text: qsTr("zoom-label") + ":"
}
ScalingLabel {
width: parent.width
wrapMode: TextEdit.Wrap
//: Interface zoom (mostly affects text and button sizes)
text: qsTr("zoom-label") + ":"
}
Slider {
id: zoomSlider
minimumValue: 0.5
maximumValue: 4.0
value: gcd.themeScale
updateValueWhileDragging: false
onValueChanged: {
gcd.themeScale = zoomSlider.value
saveSettings()
}
width: 400
}
Slider {
id: zoomSlider
minimumValue: 0.5
maximumValue: 4.0
value: gcd.themeScale
updateValueWhileDragging: false
onValueChanged: {
gcd.themeScale = zoomSlider.value
saveSettings()
}
width: 400
}
CheckBox {
id: blockUnknownToggle
checked: true
onClicked: {
if (blockUnknownToggle.checked) {
gcd.blockUnknownPeers()
} else {
gcd.allowUnknownPeers()
}
}
style: CheckBoxStyle {
label: ScalingLabel {
text: qsTr("block-unknown-label")
}
}
}
CheckBox {
id: blockUnknownToggle
checked: true
onClicked: {
if (blockUnknownToggle.checked) {
gcd.blockUnknownPeers()
} else {
gcd.allowUnknownPeers()
}
}
style: CheckBoxStyle {
label: ScalingLabel {
text: qsTr("block-unknown-label")
}
}
}
ScalingLabel {
wrapMode: TextEdit.Wrap
text: qsTr("large-text-label")
size: 20
}
ScalingLabel {
wrapMode: TextEdit.Wrap
text: qsTr("large-text-label")
size: 20
}
ScalingLabel{
width: parent.width
wrapMode: TextEdit.Wrap
//: "Default size text (scale factor: "
text: qsTr("default-scaling-text") + " " + Math.round(zoomSlider.value * 100) / 100 + ")"
}
ScalingLabel{
width: parent.width
wrapMode: TextEdit.Wrap
//: "Default size text (scale factor: "
text: qsTr("default-scaling-text") + " " + Math.round(zoomSlider.value * 100) / 100 + ")"
}
ScalingLabel {
text: qsTr("small-text-label")
size: 8
}
ScalingLabel {
text: qsTr("small-text-label")
size: 8
}
GridLayout {
columns: 2
columnSpacing: 10
GridLayout {
columns: 2
columnSpacing: 10
FlagButton {
emoji: "1f1e9-1f1ea"
locale: "de"
}
FlagButton {
emoji: "1f1e9-1f1ea"
locale: "de"
}
FlagButton {
emoji: "1f1e8-1f1e6"
locale: "en"
selected: true
}
FlagButton {
emoji: "1f1e8-1f1e6"
locale: "en"
selected: true
}
FlagButton {
locale: "fr"
emoji: "1f1eb-1f1f7"
}
FlagButton {
locale: "fr"
emoji: "1f1eb-1f1f7"
}
FlagButton {
locale: "pt"
emoji: "1f1e7-1f1f7"
}
}
FlagButton {
locale: "pt"
emoji: "1f1e7-1f1f7"
}
}
}//end of column with padding
}//end of column with padding
}//end of flickable
function saveSettings() {
@ -138,13 +138,13 @@ ColumnLayout { // settingsPane
gcd.saveSettings(zoomSlider.value, "")
}
Connections {
target: gcd
Connections {
target: gcd
onSupplySettings: function(zoom, locale, blockunknown) {
if (zoom != "") zoomSlider.value = zoom
// (locale is handled automatically by FlagButton)
blockUnknownToggle.checked = blockunknown
}
}
onSupplySettings: function(zoom, locale, blockunknown) {
if (zoom != "") zoomSlider.value = zoom
// (locale is handled automatically by FlagButton)
blockUnknownToggle.checked = blockunknown
}
}
}

View File

@ -8,8 +8,8 @@ import QtQuick.Controls.Styles 1.4
import "../styles"
Item {
id: sp
property bool running
id: sp
property bool running
Image {
id: splashImage
@ -20,17 +20,17 @@ Item {
}
ProgressBar {
id: progressBar
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: splashImage.bottom
anchors.topMargin: 10
width: splashImage.width
id: progressBar
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: splashImage.bottom
anchors.topMargin: 10
width: splashImage.width
indeterminate: true
indeterminate: true
style: ProgressBarStyle {
progress: CwtchProgress { running: sp.running }
style: ProgressBarStyle {
progress: CwtchProgress { running: sp.running }
}
}
}
}

View File

@ -3,5 +3,5 @@ import QtQuick 2.7
ComboBoxStyle {
textColor: "#000"
}
textColor: "#000"
}

View File

@ -2,20 +2,20 @@ import QtQuick.Controls.Styles 1.4
import QtQuick 2.7
ButtonStyle {
background: Rectangle {
width:25
height:25
color: windowItem.cwtch_dark_color
border.color: windowItem.cwtch_color
}
background: Rectangle {
width:25
height:25
color: windowItem.cwtch_dark_color
border.color: windowItem.cwtch_color
}
label: Text {
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.family: "Monospace"
font.pointSize: 8
color: windowItem.cwtch_background_color
text: control.text
}
}
label: Text {
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.family: "Monospace"
font.pointSize: 8
color: windowItem.cwtch_background_color
text: control.text
}
}

View File

@ -8,32 +8,32 @@ import QtQuick.Controls.Styles 1.4
Rectangle {
id: pb
border.color: "#FFFFFF"
border.width: 1
id: pb
border.color: "#FFFFFF"
border.width: 1
color: "#D2C0DD"
property bool running
color: "#D2C0DD"
property bool running
// Indeterminate animation by animating alternating stripes:
Item {
anchors.fill: parent
anchors.margins: 1
visible: control.indeterminate
clip: true
Row {
Repeater {
Rectangle {
color: index % 2 ? "#D2C0DD" : "#b29dbe"
width: 20 ; height: control.height
}
model: control.width / 20 + 2
}
XAnimator on x {
from: 0 ; to: -40
loops: Animation.Infinite
running: pb.running
}
}
}
// Indeterminate animation by animating alternating stripes:
Item {
anchors.fill: parent
anchors.margins: 1
visible: control.indeterminate
clip: true
Row {
Repeater {
Rectangle {
color: index % 2 ? "#D2C0DD" : "#b29dbe"
width: 20 ; height: control.height
}
model: control.width / 20 + 2
}
XAnimator on x {
from: 0 ; to: -40
loops: Animation.Infinite
running: pb.running
}
}
}
}

View File

@ -3,6 +3,6 @@ import QtQuick 2.7
TextAreaStyle {
textColor: "black"
backgroundColor: windowItem.cwtch_background_color
}
textColor: "black"
backgroundColor: windowItem.cwtch_background_color
}

View File

@ -3,13 +3,13 @@ import QtQuick 2.7
TextFieldStyle {
id: root
textColor: "black"
font.pointSize: 10 * gcd.themeScale
property int width: parent.width
textColor: "black"
font.pointSize: 10 * gcd.themeScale
property int width: parent.width
background: Rectangle {
radius: 2
color: windowItem.cwtch_background_color
border.color: windowItem.cwtch_color
}
}
background: Rectangle {
radius: 2
color: windowItem.cwtch_background_color
border.color: windowItem.cwtch_color
}
}

View File

@ -1,34 +1,34 @@
ThemeType {
readonly property color darkGrayPurple: "#281831"
readonly property color deepPurple: "#422850"
readonly property color mauvePurple: "#8E64A5"
readonly property color purple: "#DFB9DE"
readonly property color whitePurple: "#FFFDFF"
readonly property color softPurple: "#FDF3FC"
readonly property color pink: "#E85DA1"
readonly property color hotPink: "#D01972"
readonly property color darkGrayPurple: "#281831"
readonly property color deepPurple: "#422850"
readonly property color mauvePurple: "#8E64A5"
readonly property color purple: "#DFB9DE"
readonly property color whitePurple: "#FFFDFF"
readonly property color softPurple: "#FDF3FC"
readonly property color pink: "#E85DA1"
readonly property color hotPink: "#D01972"
backgroundMainColor: darkGrayPurple
backgroundPaneColor: deepPurple
backgroundMainColor: darkGrayPurple
backgroundPaneColor: deepPurple
mainTextColor: whitePurple
defaultButtonColor: mauvePurple
defaultButtonActiveColor: pink
defaultButtonTextColor: whitePurple
mainTextColor: whitePurple
defaultButtonColor: mauvePurple
defaultButtonActiveColor: pink
defaultButtonTextColor: whitePurple
portraitOnlineBorderColor: whitePurple
portraitOnlineBackgroundColor: darkGrayPurple
portraitOnlineTextColor: whitePurple
portraitConnectingBorderColor: mauvePurple
portraitConnectingBackgroundColor: darkGrayPurple
portraitConnectingTextColor: whitePurple
portraitOfflineBorderColor: deepPurple
portraitOfflineBackgroundColor: darkGrayPurple
portraitOfflineTextColor: softPurple
portraitOnlineBorderColor: whitePurple
portraitOnlineBackgroundColor: darkGrayPurple
portraitOnlineTextColor: whitePurple
portraitConnectingBorderColor: mauvePurple
portraitConnectingBackgroundColor: darkGrayPurple
portraitConnectingTextColor: whitePurple
portraitOfflineBorderColor: deepPurple
portraitOfflineBackgroundColor: darkGrayPurple
portraitOfflineTextColor: softPurple
portraitContactBadgeColor: hotPink
portraitContactBadgeTextColor: whitePurple
portraitProfileBadgeColor: mauvePurple
dropShadowColor: darkGrayPurple
}
portraitContactBadgeColor: hotPink
portraitContactBadgeTextColor: whitePurple
portraitProfileBadgeColor: mauvePurple
dropShadowColor: darkGrayPurple
}

View File

@ -1,34 +1,34 @@
ThemeType {
readonly property color whitePurple: "#FFFDFF"
readonly property color softPurple: "#FDF3FC"
readonly property color purple: "#DFB9DE"
readonly property color brightPurple: "#760388"
readonly property color darkPurple: "#350052"
readonly property color greyPurple: "#775F84"
readonly property color pink: "#E85DA1"
readonly property color hotPink: "#D01972"
readonly property color whitePurple: "#FFFDFF"
readonly property color softPurple: "#FDF3FC"
readonly property color purple: "#DFB9DE"
readonly property color brightPurple: "#760388"
readonly property color darkPurple: "#350052"
readonly property color greyPurple: "#775F84"
readonly property color pink: "#E85DA1"
readonly property color hotPink: "#D01972"
backgroundMainColor: whitePurple
backgroundPaneColor: softPurple
backgroundMainColor: whitePurple
backgroundPaneColor: softPurple
mainTextColor: darkPurple
defaultButtonColor: hotPink
defaultButtonActiveColor: pink
defaultButtonTextColor: whitePurple
mainTextColor: darkPurple
defaultButtonColor: hotPink
defaultButtonActiveColor: pink
defaultButtonTextColor: whitePurple
portraitOnlineBorderColor: darkPurple
portraitOnlineBackgroundColor: darkPurple
portraitOnlineTextColor: darkPurple
portraitConnectingBorderColor: greyPurple
portraitConnectingBackgroundColor: greyPurple
portraitConnectingTextColor: greyPurple
portraitOfflineBorderColor: purple
portraitOfflineBackgroundColor: purple
portraitOfflineTextColor: purple
portraitOnlineBorderColor: darkPurple
portraitOnlineBackgroundColor: darkPurple
portraitOnlineTextColor: darkPurple
portraitConnectingBorderColor: greyPurple
portraitConnectingBackgroundColor: greyPurple
portraitConnectingTextColor: greyPurple
portraitOfflineBorderColor: purple
portraitOfflineBackgroundColor: purple
portraitOfflineTextColor: purple
portraitContactBadgeColor: hotPink
portraitContactBadgeTextColor: whitePurple
portraitProfileBadgeColor: brightPurple
dropShadowColor: purple
}
portraitContactBadgeColor: hotPink
portraitContactBadgeTextColor: whitePurple
portraitProfileBadgeColor: brightPurple
dropShadowColor: purple
}

View File

@ -38,5 +38,5 @@ Item {
readonly property int sidePaneMinSize: 700
readonly property int doublePaneMinSize: 1000
property ThemeType theme: CwtchDark { }
}
property ThemeType theme: CwtchDark { }
}

View File

@ -1,31 +1,31 @@
import QtQuick 2.0
QtObject {
property color backgroundMainColor: "red"
property color backgroundPaneColor: "red"
property color backgroundMainColor: "red"
property color backgroundPaneColor: "red"
property color mainTextColor: "red"
property color defaultButtonColor: "red"
property color defaultButtonActiveColor: "red"
property color defaultButtonTextColor: "red"
property color mainTextColor: "red"
property color defaultButtonColor: "red"
property color defaultButtonActiveColor: "red"
property color defaultButtonTextColor: "red"
property color portraitOnlineBorderColor: "red"
property color portraitOnlineBackgroundColor: "red"
property color portraitOnlineTextColor: "red"
property color portraitConnectingBorderColor: "red"
property color portraitConnectingBackgroundColor: "red"
property color portraitConnectingTextColor: "red"
property color portraitOfflineBorderColor: "red"
property color portraitOfflineBackgroundColor: "red"
property color portraitOfflineTextColor: "red"
property color portraitOnlineBorderColor: "red"
property color portraitOnlineBackgroundColor: "red"
property color portraitOnlineTextColor: "red"
property color portraitConnectingBorderColor: "red"
property color portraitConnectingBackgroundColor: "red"
property color portraitConnectingTextColor: "red"
property color portraitOfflineBorderColor: "red"
property color portraitOfflineBackgroundColor: "red"
property color portraitOfflineTextColor: "red"
property color portraitContactBadgeColor: "red"
property color portraitContactBadgeTextColor: "red"
property color portraitProfileBadgeColor: "red"
property color dropShadowColor: "black"
property color portraitContactBadgeColor: "red"
property color portraitContactBadgeTextColor: "red"
property color portraitProfileBadgeColor: "red"
property color dropShadowColor: "black"
// ... more to come
// ... more to come
}
}

View File

@ -21,4 +21,4 @@ Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
}
}
}

View File

@ -15,9 +15,9 @@ Rectangle {
height: 20 * gcd.themeScale
Layout.minimumHeight: height
Layout.maximumHeight: height
color: mousedown ? Theme.defaultButtonActiveColor : Theme.defaultButtonColor
border.color: mousedown ? Theme.defaultButtonActiveColor : Theme.defaultButtonColor
border.width: 1
color: mousedown ? Theme.defaultButtonActiveColor : Theme.defaultButtonColor
border.color: mousedown ? Theme.defaultButtonActiveColor : Theme.defaultButtonColor
border.width: 1
radius: override_radius
antialiasing: true
@ -31,31 +31,31 @@ Rectangle {
signal clicked
RowLayout {
anchors.centerIn: parent
RowLayout {
anchors.centerIn: parent
Image {
anchors.left: parent.left
id: ico
source: icon!="" ? gcd.assetPath + "fontawesome/"+icon+".svg" : "";
height: button.height / 2
sourceSize.height: button.height / 2
}
Image {
anchors.left: parent.left
id: ico
source: icon!="" ? gcd.assetPath + "fontawesome/"+icon+".svg" : "";
height: button.height / 2
sourceSize.height: button.height / 2
}
Label {
id: buttonText
Label {
id: buttonText
font.family: Fonts.applicationFontRegular.name
font.styleName: "ExtraBold"
font.pixelSize: button.height / 2
color: Theme.defaultButtonTextColor
anchors.left: ico.right
anchors.leftMargin: 6
visible: button.text != "" && button.text != undefined
}
font.pixelSize: button.height / 2
color: Theme.defaultButtonTextColor
anchors.left: ico.right
anchors.leftMargin: 6
visible: button.text != "" && button.text != undefined
}
ToolTip.visible: tooltip != "" && mouseArea.containsMouse
ToolTip.text: tooltip
}
ToolTip.visible: tooltip != "" && mouseArea.containsMouse
ToolTip.text: tooltip
}
MouseArea {
@ -63,16 +63,16 @@ Rectangle {
anchors.fill: parent
onClicked: {
parent.focus = true
parent.clicked()
parent.focus = true
parent.clicked()
}
onPressed: mousedown = true
onPressed: mousedown = true
onReleased: mousedown = false
onReleased: mousedown = false
hoverEnabled: true
hoverEnabled: true
}
Keys.onSpacePressed: clicked()
}
}

View File

@ -31,17 +31,17 @@ TextField {
}
}
Widgets.Button {
icon: ""
text: button_text
anchors { top: parent.top; right: parent.right }
Widgets.Button {
icon: ""
text: button_text
anchors { top: parent.top; right: parent.right }
override_radius: 10
height: parent.height; width: parent.height * 4
onClicked: {
parent.focus = true;
onClicked: {
parent.focus = true;
parent.clicked();
}
}
}
}
}
}

View File

@ -6,9 +6,9 @@ import QtQuick.Layouts 1.3
import "../theme"
ColumnLayout {
id: root
id: root
property alias dualPane: myprof.dualPane
property alias dualPane: myprof.dualPane
MouseArea {
@ -20,26 +20,26 @@ ColumnLayout {
}
MyProfile { // CURRENT PROFILE INFO AND CONTROL BAR
id: myprof
}
id: myprof
}
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
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.AsNeeded
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded
background: Rectangle {
implicitWidth: 6
@ -50,15 +50,15 @@ ColumnLayout {
implicitHeight:1
color: Theme.backgroundPaneColor
}
}
}
ColumnLayout {
id: colContacts
width: root.width
spacing: 0
id: colContacts
width: root.width
spacing: 0
Connections { // ADD/REMOVE CONTACT ENTRIES
target: gcd
Connections { // ADD/REMOVE CONTACT ENTRIES
target: gcd
onAddContact: function(handle, displayName, image, badge, status, blocked, loading, lastMsgTs) {
@ -77,33 +77,33 @@ ColumnLayout {
}
var newContact = {
"_handle": handle,
"_displayName": displayName + (blocked ? " (blocked)" : "" ),
"_image": image,
"_badge": badge,
"_status": status,
"_blocked": blocked,
"_loading": loading,
"_loading": loading,
"_lastMsgTs": lastMsgTs
}
"_handle": handle,
"_displayName": displayName + (blocked ? " (blocked)" : "" ),
"_image": image,
"_badge": badge,
"_status": status,
"_blocked": blocked,
"_loading": loading,
"_loading": loading,
"_lastMsgTs": lastMsgTs
}
contactsModel.insert(index, newContact)
}
contactsModel.insert(index, newContact)
}
onRemoveContact: function(handle) {
for(var i = 0; i < contactsModel.count; i++){
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
}
}
}
}
onIncContactUnreadCount: function(handle) {
var ts = Math.round((new Date()).getTime() / 1000);
for(var i = 0; i < contactsModel.count; i++){
onIncContactUnreadCount: function(handle) {
var ts = Math.round((new Date()).getTime() / 1000);
for(var i = 0; i < contactsModel.count; i++){
if(contactsModel.get(i)["_handle"] == handle) {
var contact = contactsModel.get(i)
contact["_lastMsgTs"] = ts
@ -112,31 +112,31 @@ ColumnLayout {
}
}
onResetProfile: function() {
contactsModel.clear()
}
}
onResetProfile: function() {
contactsModel.clear()
}
}
ListModel { // CONTACT OBJECTS ARE STORED HERE ...
id: contactsModel
}
ListModel { // CONTACT OBJECTS ARE STORED HERE ...
id: contactsModel
}
Repeater {
model: contactsModel // ... AND DISPLAYED HERE
delegate: ContactRow {
handle: _handle
displayName: _displayName
image: _image
badge: _badge
status: _status
blocked: _blocked
Repeater {
model: contactsModel // ... AND DISPLAYED HERE
delegate: ContactRow {
handle: _handle
displayName: _displayName
image: _image
badge: _badge
status: _status
blocked: _blocked
loading: _loading
}
}
}
}
}
}
}
}
}

View File

@ -12,7 +12,7 @@ import QtQuick.Controls.Styles 1.4
PortraitRow {
property int status: 0
property int status: 0
property int badge
property bool loading
@ -28,24 +28,24 @@ PortraitRow {
}
ProgressBar { // LOADING ?
id: loadingProgress
property bool running
running: loading
visible: loading
id: loadingProgress
property bool running
running: loading
visible: loading
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 1 * gcd.themeScale
anchors.rightMargin: 25 * gcd.themeScale
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 1 * gcd.themeScale
anchors.rightMargin: 25 * gcd.themeScale
height: parent.height * .1
width: 100 * gcd.themeScale
height: parent.height * .1
width: 100 * gcd.themeScale
indeterminate: true
indeterminate: true
style: ProgressBarStyle {
progress: CwtchProgress { running: loadingProgress.running}
}
style: ProgressBarStyle {
progress: CwtchProgress { running: loadingProgress.running}
}
}
onClicked: function(handle) {
@ -59,39 +59,39 @@ PortraitRow {
}
}
Component.onCompleted: { setColors(status) }
Component.onCompleted: { setColors(status) }
onStatusChanged: { setColors(status) }
onStatusChanged: { setColors(status) }
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) {
//-2:WtfCodeError,-1:Error,0:Disconnected,1:Connecting,2:Connected,3:Authenticated,4:Synced,5:Failed,6:Killed
if (status == 4 || status == 3) {
portraitBorderColor = Theme.portraitOnlineBorderColor
portraitColor = Theme.portraitOnlineBackgroundColor
nameColor = Theme.portraitOnlineTextColor
onionColor = Theme.portraitOnlineTextColor
} else if (status == 2 || status == 1) {
} else if (status == 2 || status == 1) {
portraitBorderColor = Theme.portraitConnectingBorderColor
portraitColor = Theme.portraitConnectingBackgroundColor
nameColor = Theme.portraitConnectingTextColor
onionColor = Theme.portraitConnectingTextColor
} else {
} else {
portraitBorderColor = Theme.portraitOfflineBorderColor
portraitColor = Theme.portraitOfflineBackgroundColor
nameColor = Theme.portraitOfflineTextColor
onionColor = Theme.portraitOfflineTextColor
}
}
}
Connections { // UPDATE UNREAD MESSAGES COUNTER
target: gcd
onUpdateContactStatus: function(_handle, _status, _loading) {
if (handle == _handle) {
status = _status
loadingProgress.visible = loadingProgress.running = loading = _loading
}
}
if (handle == _handle) {
status = _status
loadingProgress.visible = loadingProgress.running = loading = _loading
}
}
onIncContactUnreadCount: function(handle) {
if (handle == _handle && gcd.selectedConversation != handle) {
@ -99,4 +99,4 @@ PortraitRow {
}
}
}
}
}

View File

@ -24,7 +24,7 @@ Item {
Label {
id: label
textFormat: Text.PlainText
textFormat: Text.PlainText
elide: Text.ElideRight
text: textMetric.text
@ -37,7 +37,7 @@ Item {
}
/*onWidthChanged: {
setTextResize()
setTextResize()
}*/
onTextChanged: {
@ -54,4 +54,4 @@ Item {
}
}
}
}

View File

@ -10,391 +10,391 @@ import "../fonts/MutantStandard.js" as Mutant
import "controls"
Item {
id: root
height: 0
property int size: 24
property int requestedHeight: size * 8
property string morph: "clw"
property string color: "v1"
property bool narrowMode: width < (txtSearch.width + root.size * 14 + btnX.width)
signal picked(string shortcode)
signal slideopen()
signal slideclosed()
visible: height != 0
id: root
height: 0
property int size: 24
property int requestedHeight: size * 8
property string morph: "clw"
property string color: "v1"
property bool narrowMode: width < (txtSearch.width + root.size * 14 + btnX.width)
signal picked(string shortcode)
signal slideopen()
signal slideclosed()
visible: height != 0
Rectangle {
color: windowItem.cwtch_dark_color
anchors.fill: parent
}
Rectangle {
color: windowItem.cwtch_dark_color
anchors.fill: parent
}
PropertyAnimation {
id: animClose;
target: root;
properties: "height";
to: 0;
duration: 400;
}
PropertyAnimation {
id: animClose;
target: root;
properties: "height";
to: 0;
duration: 400;
}
PropertyAnimation {
id: animOpen;
target: root;
properties: "height";
to: requestedHeight;
duration: 400;
}
PropertyAnimation {
id: animOpen;
target: root;
properties: "height";
to: requestedHeight;
duration: 400;
}
Button {
id: btnX
anchors.top: parent.top
anchors.right: parent.right
text: "x"
Button {
id: btnX
anchors.top: parent.top
anchors.right: parent.right
text: "x"
onClicked: animClose.start()
}
onClicked: animClose.start()
}
ColumnLayout {
anchors.fill: parent
ColumnLayout {
anchors.fill: parent
RowLayout {
TextField {
id: txtSearch
//: Search...
placeholderText: qsTr("search")
onTextChanged: {
if (text == "") emojiModel.model = folder_expressions
else emojiModel.model = folder_search
emojiModel.updatefilters()
}
}
RowLayout {
TextField {
id: txtSearch
//: Search...
placeholderText: qsTr("search")
onTextChanged: {
if (text == "") emojiModel.model = folder_expressions
else emojiModel.model = folder_search
emojiModel.updatefilters()
}
}
ImageButton {
id: btnEmojiExpressionsGroup
visible: !root.narrowMode
//: Expressions
tooltip: qsTr("emojicat-expressions")
source: gcd.assetPath + "mutstd/smile.webp"
size: root.size
onClicked: emojiModel.model = folder_expressions
}
ImageButton {
visible: !root.narrowMode
//: Activities
tooltip: qsTr("emojicat-activities")
source: gcd.assetPath + "mutstd/artist_r1.webp"
size: root.size
onClicked: emojiModel.model = folder_activities_clothing
}
ImageButton {
visible: !root.narrowMode
//: Food, drink & herbs
tooltip: qsTr("emojicat-food")
source: gcd.assetPath + "mutstd/red_apple.webp"
size: root.size
onClicked: emojiModel.model = folder_food_drink_herbs
}
ImageButton {
visible: !root.narrowMode
//: Gender, relationships & sexuality
tooltip: qsTr("emojicat-gender")
size: root.size
source: gcd.assetPath + "mutstd/pride_100.webp"
onClicked: emojiModel.model = folder_gsr
}
ImageButton {
visible: !root.narrowMode
//: Nature and effects
tooltip: qsTr("emojicat-nature")
source: gcd.assetPath + "mutstd/sun_behind_small_cloud.webp"
size: root.size
onClicked: emojiModel.model = folder_nature
}
ImageButton {
visible: !root.narrowMode
//: Objects
tooltip: qsTr("emojicat-objects")
source: gcd.assetPath + "mutstd/crystal_ball.webp"
size: root.size
onClicked: emojiModel.model = folder_objects
}
ImageButton {
visible: !root.narrowMode
//: People and animals
tooltip: qsTr("emojicat-people")
source: gcd.assetPath + "mutstd/crow.webp"
size: root.size
onClicked: emojiModel.model = folder_people
}
ImageButton {
visible: !root.narrowMode
//: Symbols
tooltip: qsTr("emojicat-symbols")
source: gcd.assetPath + "mutstd/purple_heart.webp"
size: root.size
onClicked: emojiModel.model = folder_symbols
}
ImageButton {
visible: !root.narrowMode
//: Travel & places
tooltip: qsTr("emojicat-travel")
source: gcd.assetPath + "mutstd/airplane.webp"
size: root.size
onClicked: emojiModel.model = folder_travel_places
}
ImageButton {
visible: !root.narrowMode
//: Miscellaneous
tooltip: qsTr("emojicat-misc")
source: gcd.assetPath + "mutstd/hash_char.webp"
size: root.size
onClicked: emojiModel.model = folder_utils
}
ImageButton {
visible: !root.narrowMode
id: btnUndefinedGroup
// (no tooltip; this is a catchall group meant to detect unclassified emoji during development)
//TODO: remove this category upon finalizing the Emoji Drawer
source: gcd.assetPath + "mutstd/undefined_character.webp"
size: root.size
onClicked: emojiModel.model = folder_other
}
ImageButton {
id: btnEmojiExpressionsGroup
visible: !root.narrowMode
//: Expressions
tooltip: qsTr("emojicat-expressions")
source: gcd.assetPath + "mutstd/smile.webp"
size: root.size
onClicked: emojiModel.model = folder_expressions
}
ImageButton {
visible: !root.narrowMode
//: Activities
tooltip: qsTr("emojicat-activities")
source: gcd.assetPath + "mutstd/artist_r1.webp"
size: root.size
onClicked: emojiModel.model = folder_activities_clothing
}
ImageButton {
visible: !root.narrowMode
//: Food, drink & herbs
tooltip: qsTr("emojicat-food")
source: gcd.assetPath + "mutstd/red_apple.webp"
size: root.size
onClicked: emojiModel.model = folder_food_drink_herbs
}
ImageButton {
visible: !root.narrowMode
//: Gender, relationships & sexuality
tooltip: qsTr("emojicat-gender")
size: root.size
source: gcd.assetPath + "mutstd/pride_100.webp"
onClicked: emojiModel.model = folder_gsr
}
ImageButton {
visible: !root.narrowMode
//: Nature and effects
tooltip: qsTr("emojicat-nature")
source: gcd.assetPath + "mutstd/sun_behind_small_cloud.webp"
size: root.size
onClicked: emojiModel.model = folder_nature
}
ImageButton {
visible: !root.narrowMode
//: Objects
tooltip: qsTr("emojicat-objects")
source: gcd.assetPath + "mutstd/crystal_ball.webp"
size: root.size
onClicked: emojiModel.model = folder_objects
}
ImageButton {
visible: !root.narrowMode
//: People and animals
tooltip: qsTr("emojicat-people")
source: gcd.assetPath + "mutstd/crow.webp"
size: root.size
onClicked: emojiModel.model = folder_people
}
ImageButton {
visible: !root.narrowMode
//: Symbols
tooltip: qsTr("emojicat-symbols")
source: gcd.assetPath + "mutstd/purple_heart.webp"
size: root.size
onClicked: emojiModel.model = folder_symbols
}
ImageButton {
visible: !root.narrowMode
//: Travel & places
tooltip: qsTr("emojicat-travel")
source: gcd.assetPath + "mutstd/airplane.webp"
size: root.size
onClicked: emojiModel.model = folder_travel_places
}
ImageButton {
visible: !root.narrowMode
//: Miscellaneous
tooltip: qsTr("emojicat-misc")
source: gcd.assetPath + "mutstd/hash_char.webp"
size: root.size
onClicked: emojiModel.model = folder_utils
}
ImageButton {
visible: !root.narrowMode
id: btnUndefinedGroup
// (no tooltip; this is a catchall group meant to detect unclassified emoji during development)
//TODO: remove this category upon finalizing the Emoji Drawer
source: gcd.assetPath + "mutstd/undefined_character.webp"
size: root.size
onClicked: emojiModel.model = folder_other
}
Item {
visible: root.narrowMode
height: root.size
width: root.size
Item {
visible: root.narrowMode
height: root.size
width: root.size
Image {
id: imgCatRot
anchors.centerIn: parent
source: cats[index].source
property int index: 0
property var cats: [
{source: gcd.assetPath + "mutstd/smile.webp", model: folder_expressions},
{source: gcd.assetPath + "mutstd/artist_r1.webp", model: folder_activities_clothing},
{source: gcd.assetPath + "mutstd/red_apple.webp", model: folder_food_drink_herbs},
{source: gcd.assetPath + "mutstd/pride_100.webp", model: folder_gsr},
{source: gcd.assetPath + "mutstd/sun_behind_small_cloud.webp", model: folder_nature},
{source: gcd.assetPath + "mutstd/crystal_ball.webp", model: folder_objects},
{source: gcd.assetPath + "mutstd/crow.webp", model: folder_people},
{source: gcd.assetPath + "mutstd/purple_heart.webp", model: folder_symbols},
{source: gcd.assetPath + "mutstd/airplane.webp", model: folder_travel_places},
{source: gcd.assetPath + "mutstd/hash_char.webp", model: folder_utils},
{source: gcd.assetPath + "mutstd/undefined_character.webp", model: folder_other}
Image {
id: imgCatRot
anchors.centerIn: parent
source: cats[index].source
property int index: 0
property var cats: [
{source: gcd.assetPath + "mutstd/smile.webp", model: folder_expressions},
{source: gcd.assetPath + "mutstd/artist_r1.webp", model: folder_activities_clothing},
{source: gcd.assetPath + "mutstd/red_apple.webp", model: folder_food_drink_herbs},
{source: gcd.assetPath + "mutstd/pride_100.webp", model: folder_gsr},
{source: gcd.assetPath + "mutstd/sun_behind_small_cloud.webp", model: folder_nature},
{source: gcd.assetPath + "mutstd/crystal_ball.webp", model: folder_objects},
{source: gcd.assetPath + "mutstd/crow.webp", model: folder_people},
{source: gcd.assetPath + "mutstd/purple_heart.webp", model: folder_symbols},
{source: gcd.assetPath + "mutstd/airplane.webp", model: folder_travel_places},
{source: gcd.assetPath + "mutstd/hash_char.webp", model: folder_utils},
{source: gcd.assetPath + "mutstd/undefined_character.webp", model: folder_other}
]
height: root.size * (maCatRot.pressed ? 0.8 : 1.0)
width: root.size * (maCatRot.pressed ? 0.8 : 1.0)
height: root.size * (maCatRot.pressed ? 0.8 : 1.0)
width: root.size * (maCatRot.pressed ? 0.8 : 1.0)
ToolTip.visible: maCatRot.containsMouse
ToolTip.text: gcd.os == "android" ? qsTr("cycle-cats-android") : qsTr("cycle-cats-desktop")
ToolTip.visible: maCatRot.containsMouse
ToolTip.text: gcd.os == "android" ? qsTr("cycle-cats-android") : qsTr("cycle-cats-desktop")
MouseArea {
id: maCatRot
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent;
MouseArea {
id: maCatRot
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent;
onClicked: {
if (mouse.button == Qt.RightButton) {//todo: long press on android
imgCatRot.index = 0
} else {
imgCatRot.index = (imgCatRot.index + 1) % imgCatRot.cats.length
}
emojiModel.model = imgCatRot.cats[imgCatRot.index].model
//root.morph = Mutant.standard.morphs[imgMorph.index]
//emojiModel.updatefilters()
}
}
}
}
onClicked: {
if (mouse.button == Qt.RightButton) {//todo: long press on android
imgCatRot.index = 0
} else {
imgCatRot.index = (imgCatRot.index + 1) % imgCatRot.cats.length
}
emojiModel.model = imgCatRot.cats[imgCatRot.index].model
//root.morph = Mutant.standard.morphs[imgMorph.index]
//emojiModel.updatefilters()
}
}
}
}
Item {
height: root.size
width: root.size
Item {
height: root.size
width: root.size
Image {
id: imgMorph
anchors.centerIn: parent
source: gcd.assetPath + "mutstd/hand_"+Mutant.standard.morphs[index]+"_"+root.color+".webp"
property int index: 0
height: root.size
width: root.size
Image {
id: imgMorph
anchors.centerIn: parent
source: gcd.assetPath + "mutstd/hand_"+Mutant.standard.morphs[index]+"_"+root.color+".webp"
property int index: 0
height: root.size
width: root.size
ToolTip.visible: maMorph.containsMouse
ToolTip.text: gcd.os == "android" ? qsTr("cycle-morphs-android") : qsTr("cycle-morphs-desktop")
ToolTip.visible: maMorph.containsMouse
ToolTip.text: gcd.os == "android" ? qsTr("cycle-morphs-android") : qsTr("cycle-morphs-desktop")
MouseArea {
id: maMorph
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent;
onClicked: {
if (mouse.button == Qt.RightButton) {//todo: long press on android
imgMorph.index = 0//TODO: saved morph
} else {
imgMorph.index = (imgMorph.index + 1) % Mutant.standard.morphs.length
}
root.morph = Mutant.standard.morphs[imgMorph.index]
emojiModel.updatefilters()
}
}
}
}
MouseArea {
id: maMorph
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent;
onClicked: {
if (mouse.button == Qt.RightButton) {//todo: long press on android
imgMorph.index = 0//TODO: saved morph
} else {
imgMorph.index = (imgMorph.index + 1) % Mutant.standard.morphs.length
}
root.morph = Mutant.standard.morphs[imgMorph.index]
emojiModel.updatefilters()
}
}
}
}
Item {
height: root.size
width: root.size
Item {
height: root.size
width: root.size
Image {
id: imgColor
anchors.centerIn: parent
source: gcd.assetPath + "mutstd/color_modifier_"+Mutant.standard.colorByIndex(index, root.morph)+".webp"
property int index: 0
height: root.size
width: root.size
Image {
id: imgColor
anchors.centerIn: parent
source: gcd.assetPath + "mutstd/color_modifier_"+Mutant.standard.colorByIndex(index, root.morph)+".webp"
property int index: 0
height: root.size
width: root.size
ToolTip.visible: ma.containsMouse
ToolTip.text: gcd.os == "android" ? qsTr("cycle-colours-android") : qsTr("cycle-colours-desktop")
ToolTip.visible: ma.containsMouse
ToolTip.text: gcd.os == "android" ? qsTr("cycle-colours-android") : qsTr("cycle-colours-desktop")
MouseArea {
id: ma
anchors.fill: parent;
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
MouseArea {
id: ma
anchors.fill: parent;
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: function(mouse){
if (mouse.button == Qt.RightButton) {//todo: long press on android
imgColor.index = 0//todo: saved color
} else {
imgColor.index = (imgColor.index + 1) % Mutant.standard.numColors(root.morph)
}
root.color = Mutant.standard.colorByIndex(imgColor.index, root.morph)
emojiModel.updatefilters()
}
}
}
}
}
onClicked: function(mouse){
if (mouse.button == Qt.RightButton) {//todo: long press on android
imgColor.index = 0//todo: saved color
} else {
imgColor.index = (imgColor.index + 1) % Mutant.standard.numColors(root.morph)
}
root.color = Mutant.standard.colorByIndex(imgColor.index, root.morph)
emojiModel.updatefilters()
}
}
}
}
}
GridView {
Layout.fillWidth: true
Layout.fillHeight: true
height: root.size * 3
cellWidth: root.size
cellHeight: root.size
clip: true
ScrollBar.vertical: ScrollBar {}
maximumFlickVelocity: 1250
boundsBehavior: GridView.StopAtBounds
GridView {
Layout.fillWidth: true
Layout.fillHeight: true
height: root.size * 3
cellWidth: root.size
cellHeight: root.size
clip: true
ScrollBar.vertical: ScrollBar {}
maximumFlickVelocity: 1250
boundsBehavior: GridView.StopAtBounds
model: emojiModel
}
}
model: emojiModel
}
}
ListModel { id: folder_activities_clothing }
ListModel { id: folder_expressions }
ListModel { id: folder_food_drink_herbs }
ListModel { id: folder_gsr }
ListModel { id: folder_nature }
ListModel { id: folder_objects }
ListModel { id: folder_people }
ListModel { id: folder_symbols }
ListModel { id: folder_travel_places }
ListModel { id: folder_utils }
ListModel { id: folder_other }
ListModel { id: folder_search }
ListModel { id: folder_activities_clothing }
ListModel { id: folder_expressions }
ListModel { id: folder_food_drink_herbs }
ListModel { id: folder_gsr }
ListModel { id: folder_nature }
ListModel { id: folder_objects }
ListModel { id: folder_people }
ListModel { id: folder_symbols }
ListModel { id: folder_travel_places }
ListModel { id: folder_utils }
ListModel { id: folder_other }
ListModel { id: folder_search }
DelegateModel {
id: emojiModel
model: folder_expressions
DelegateModel {
id: emojiModel
model: folder_expressions
delegate: Item {
width: root.size
height: root.size
delegate: Item {
width: root.size
height: root.size
Image {
id: img
//source: "file://" + gcd.binaryPath + "/assets/mutstd/" + code + ".webp"
source: gcd.assetPath + "mutstd/" + code + ".webp"
width: root.size * (mouseArea.pressed ? 0.7 : 0.8)
height: width
anchors.centerIn: parent
property string shortcode: code
Image {
id: img
//source: "file://" + gcd.binaryPath + "/assets/mutstd/" + code + ".webp"
source: gcd.assetPath + "mutstd/" + code + ".webp"
width: root.size * (mouseArea.pressed ? 0.7 : 0.8)
height: width
anchors.centerIn: parent
property string shortcode: code
ToolTip.visible: mouseArea.containsMouse
ToolTip.text: desc + "\n:" + shortcode + ":"
ToolTip.visible: mouseArea.containsMouse
ToolTip.text: desc + "\n:" + shortcode + ":"
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: root.picked(img.shortcode)
}
}
}
onClicked: root.picked(img.shortcode)
}
}
}
Component.onCompleted: updatefilters()
Component.onCompleted: updatefilters()
function clearall() {
folder_activities_clothing.clear()
folder_expressions.clear()
folder_food_drink_herbs.clear()
folder_gsr.clear()
folder_nature.clear()
folder_objects.clear()
folder_people.clear()
folder_symbols.clear()
folder_travel_places.clear()
folder_utils.clear()
folder_other.clear()
folder_search.clear()
}
function clearall() {
folder_activities_clothing.clear()
folder_expressions.clear()
folder_food_drink_herbs.clear()
folder_gsr.clear()
folder_nature.clear()
folder_objects.clear()
folder_people.clear()
folder_symbols.clear()
folder_travel_places.clear()
folder_utils.clear()
folder_other.clear()
folder_search.clear()
}
function updatefilters() {
clearall()
function updatefilters() {
clearall()
for (var i in Mutant.standard.manifest) {
if (typeof Mutant.standard.manifest[i].morph !== "undefined" && Mutant.standard.manifest[i].morph != root.morph)
continue;
for (var i in Mutant.standard.manifest) {
if (typeof Mutant.standard.manifest[i].morph !== "undefined" && Mutant.standard.manifest[i].morph != root.morph)
continue;
if (typeof Mutant.standard.manifest[i].color !== "undefined" && Mutant.standard.manifest[i].color != root.color)
continue;
if (typeof Mutant.standard.manifest[i].color !== "undefined" && Mutant.standard.manifest[i].color != root.color)
continue;
if (txtSearch.text != "" && !(Mutant.standard.manifest[i].code.includes(txtSearch.text) || Mutant.standard.manifest[i].desc.includes(txtSearch.text))) {
continue;
}
if (txtSearch.text != "" && !(Mutant.standard.manifest[i].code.includes(txtSearch.text) || Mutant.standard.manifest[i].desc.includes(txtSearch.text))) {
continue;
}
var model = folder_other
if (txtSearch.text == "") {
switch(Mutant.standard.manifest[i].cat) {
case "activities_clothing": model = folder_activities_clothing; break;
case "expressions": model = folder_expressions; break;
case "symbols": model = folder_symbols; break;
case "food_drink_herbs": model = folder_food_drink_herbs; break;
case "gsr": model = folder_gsr; break;
case "nature": model = folder_nature; break;
case "objects": model = folder_objects; break;
case "people": model = folder_people; break;
case "travel_places": model = folder_travel_places; break;
case "utils": model = folder_utils; break;
}
} else {
model = folder_search
}
var model = folder_other
if (txtSearch.text == "") {
switch(Mutant.standard.manifest[i].cat) {
case "activities_clothing": model = folder_activities_clothing; break;
case "expressions": model = folder_expressions; break;
case "symbols": model = folder_symbols; break;
case "food_drink_herbs": model = folder_food_drink_herbs; break;
case "gsr": model = folder_gsr; break;
case "nature": model = folder_nature; break;
case "objects": model = folder_objects; break;
case "people": model = folder_people; break;
case "travel_places": model = folder_travel_places; break;
case "utils": model = folder_utils; break;
}
} else {
model = folder_search
}
model.append({
cat: Mutant.standard.manifest[i].cat,
code: Mutant.standard.manifest[i].code,
color: Mutant.standard.manifest[i].color,
morph: Mutant.standard.manifest[i].morph,
desc: Mutant.standard.manifest[i].desc
})
}
}
}
model.append({
cat: Mutant.standard.manifest[i].cat,
code: Mutant.standard.manifest[i].code,
color: Mutant.standard.manifest[i].color,
morph: Mutant.standard.manifest[i].morph,
desc: Mutant.standard.manifest[i].desc
})
}
}
}
onSlideopen: animOpen.start()
onSlideclosed: animClose.start()
}
onSlideopen: animOpen.start()
onSlideclosed: animClose.start()
}

View File

@ -8,54 +8,54 @@ import "../widgets" as Widgets
Item {
id: root
height: lbl.visible ? lbl.height : txt.height + (gcd.os == "android" ? btn.height + 3 : 0) //lbl.height
implicitHeight: height //lbl.height
id: root
height: lbl.visible ? lbl.height : txt.height + (gcd.os == "android" ? btn.height + 3 : 0) //lbl.height
implicitHeight: height //lbl.height
property alias text: lbl.text
signal updated
property alias text: lbl.text
signal updated
Text { // DISPLAY THE TEXT IN READONLY MODE
id: lbl
fontSizeMode: Text.HorizontalFit
font.pixelSize: 36
minimumPixelSize: 8
horizontalAlignment: Text.AlignHCenter
textFormat: Text.PlainText
anchors.horizontalCenter: parent.horizontalCenter
}
Text { // DISPLAY THE TEXT IN READONLY MODE
id: lbl
fontSizeMode: Text.HorizontalFit
font.pixelSize: 36
minimumPixelSize: 8
horizontalAlignment: Text.AlignHCenter
textFormat: Text.PlainText
anchors.horizontalCenter: parent.horizontalCenter
}
Image {
id: img
anchors.left: lbl.right
anchors.leftMargin: 3
source: gcd.assetPath + "fontawesome/solid/edit.svg"
height: 16
sourceSize.height: 16
}
Image {
id: img
anchors.left: lbl.right
anchors.leftMargin: 3
source: gcd.assetPath + "fontawesome/solid/edit.svg"
height: 16
sourceSize.height: 16
}
MouseArea {
anchors.fill: lbl
MouseArea {
anchors.fill: lbl
onClicked: {
lbl.visible = img.visible = false
txt.visible = true
if (gcd.os == "android") btn.visible = true
txt.text = lbl.text
txt.selectAll()
txt.focus = true
}
}
onClicked: {
lbl.visible = img.visible = false
txt.visible = true
if (gcd.os == "android") btn.visible = true
txt.text = lbl.text
txt.selectAll()
txt.focus = true
}
}
TextEdit { // MAKE IT AN EDITOR WHEN EDITING
id: txt
text: root.text
visible: false
selectByMouse: true
font.pixelSize: lbl.font.pixelSize
anchors.horizontalCenter: parent.horizontalCenter
TextEdit { // MAKE IT AN EDITOR WHEN EDITING
id: txt
text: root.text
visible: false
selectByMouse: true
font.pixelSize: lbl.font.pixelSize
anchors.horizontalCenter: parent.horizontalCenter
onActiveFocusChanged: {
@ -64,29 +64,29 @@ Item {
}
}
Keys.onReturnPressed: {
if (event.modifiers == Qt.NoModifier) {
save()
}
}
Keys.onReturnPressed: {
if (event.modifiers == Qt.NoModifier) {
save()
}
}
function save() {
function save() {
root.text = txt.text
txt.visible = btn.visible = false
lbl.visible = img.visible = true
root.updated(txt.text)
}
}
}
}
Widgets.Button {
id: btn
anchors.top: txt.bottom
anchors.topMargin: 3
anchors.horizontalCenter: parent.horizontalCenter
visible: false
text: qsTr("Update")
Widgets.Button {
id: btn
anchors.top: txt.bottom
anchors.topMargin: 3
anchors.horizontalCenter: parent.horizontalCenter
visible: false
text: qsTr("Update")
onClicked: txt.save()
}
}
onClicked: txt.save()
}
}

View File

@ -7,170 +7,170 @@ import QtQuick.Layouts 1.3
import "controls" as Awesome
Item {
id: root
id: root
anchors.left: fromMe ? undefined : parent.left
anchors.right: fromMe ? parent.right : undefined
height: Math.max(imgProfile.height, rectMessageBubble.height)
anchors.left: fromMe ? undefined : parent.left
anchors.right: fromMe ? parent.right : undefined
height: Math.max(imgProfile.height, rectMessageBubble.height)
property string message
property string rawMessage
property string from
property string handle
property string displayName
property string messageID
property bool fromMe
property bool ackd
property alias timestamp: ts.text
property alias image: imgProfile.source
property string error
property string message
property string rawMessage
property string from
property string handle
property string displayName
property string messageID
property bool fromMe
property bool ackd
property alias timestamp: ts.text
property alias image: imgProfile.source
property string error
Connections {
target: gcd
Connections {
target: gcd
onAcknowledged: function(mid) {
if (mid == messageID) {
root.ackd = true
}
}
onAcknowledged: function(mid) {
if (mid == messageID) {
root.ackd = true
}
}
onGroupSendError: function(mid, error) {
if (mid == messageID) {
root.error = error
}
}
}
onGroupSendError: function(mid, error) {
if (mid == messageID) {
root.error = error
}
}
}
Portrait {
id: imgProfile
anchors.left: parent.left
// TODO: currently unused?
//handle: root.from
visible: !fromMe
//showStatus: false
//highlight: ima.containsMouse
Portrait {
id: imgProfile
anchors.left: parent.left
// TODO: currently unused?
//handle: root.from
visible: !fromMe
//showStatus: false
//highlight: ima.containsMouse
ToolTip.visible: ima.containsMouse
//: Click to DM
ToolTip.text: qsTr("dm-tooltip")
ToolTip.visible: ima.containsMouse
//: Click to DM
ToolTip.text: qsTr("dm-tooltip")
MouseArea {
id: ima
anchors.fill: parent
hoverEnabled: overlay.inGroup
MouseArea {
id: ima
anchors.fill: parent
hoverEnabled: overlay.inGroup
onClicked: {
gcd.createContact(from)
gcd.broadcast("ResetMessagePane")
theStack.pane = theStack.messagePane
gcd.loadMessagesPane(from)
overlayStack.overlay = overlayStack.chatOverlay
}
}
onClicked: {
gcd.createContact(from)
gcd.broadcast("ResetMessagePane")
theStack.pane = theStack.messagePane
gcd.loadMessagesPane(from)
overlayStack.overlay = overlayStack.chatOverlay
}
}
}
}
Rectangle { // THIS IS JUST A PRETTY MESSAGE-HOLDING RECTANGLE
id: rectMessageBubble
height: colMessageBubble.height + 8
width: colMessageBubble.width + 6
color: fromMe ? "#B09CBC" : "#4B3557"
radius: 5
Rectangle { // THIS IS JUST A PRETTY MESSAGE-HOLDING RECTANGLE
id: rectMessageBubble
height: colMessageBubble.height + 8
width: colMessageBubble.width + 6
color: fromMe ? "#B09CBC" : "#4B3557"
radius: 5
// the console will complain constantly about me setting these anchors, but qt only allows margins if they've been set to something
// a kludge to fix this would be to have spacers before/after and set the widths according to the side they're on ^ea
anchors.left: fromMe ? undefined : imgProfile.right //parent.left
anchors.right: fromMe ? parent.right : undefined
anchors.leftMargin: 5
anchors.rightMargin: 9
anchors.topMargin: 5
// the console will complain constantly about me setting these anchors, but qt only allows margins if they've been set to something
// a kludge to fix this would be to have spacers before/after and set the widths according to the side they're on ^ea
anchors.left: fromMe ? undefined : imgProfile.right //parent.left
anchors.right: fromMe ? parent.right : undefined
anchors.leftMargin: 5
anchors.rightMargin: 9
anchors.topMargin: 5
ColumnLayout {
id: colMessageBubble
ColumnLayout {
id: colMessageBubble
Column { // combine these into one element or else childrenRect won't play nicely
TextEdit { // this is used as a helper to calculate the message box width
id: dummy
visible: false
padding: 6
leftPadding: 10
font.pixelSize: gcd.themeScale * 12
wrapMode: TextEdit.NoWrap
text: lbl.text
textFormat: Text.RichText
}
Column { // combine these into one element or else childrenRect won't play nicely
TextEdit { // this is used as a helper to calculate the message box width
id: dummy
visible: false
padding: 6
leftPadding: 10
font.pixelSize: gcd.themeScale * 12
wrapMode: TextEdit.NoWrap
text: lbl.text
textFormat: Text.RichText
}
TextEdit { // this is the actual text display
id: lbl
text: parse(message, 12, true)
color: "#FFFFFF"
padding: 6
leftPadding: 10
font.pixelSize: gcd.themeScale * 12
selectByMouse: gcd.os != "android"
readOnly: true
width: Math.min(dummy.width, root.parent.width - (imgProfile.visible ? imgProfile.width : 0) - 40)
wrapMode: TextEdit.Wrap
textFormat: Text.RichText
}
}
TextEdit { // this is the actual text display
id: lbl
text: parse(message, 12, true)
color: "#FFFFFF"
padding: 6
leftPadding: 10
font.pixelSize: gcd.themeScale * 12
selectByMouse: gcd.os != "android"
readOnly: true
width: Math.min(dummy.width, root.parent.width - (imgProfile.visible ? imgProfile.width : 0) - 40)
wrapMode: TextEdit.Wrap
textFormat: Text.RichText
}
}
RowLayout {
id: rowBottom
anchors.left: parent.left
anchors.right: parent.right
RowLayout {
id: rowBottom
anchors.left: parent.left
anchors.right: parent.right
Label { // TIMESTAMP
id: ts
color: "#FFFFFF"
font.pixelSize: 10 * gcd.themeScale
anchors.left: parent.left
leftPadding: 10
}
Label { // TIMESTAMP
id: ts
color: "#FFFFFF"
font.pixelSize: 10 * gcd.themeScale
anchors.left: parent.left
leftPadding: 10
}
Label { // DISPLAY NAME FOR GROUPS
color: "#FFFFFF"
font.pixelSize: 10 * gcd.themeScale
anchors.right: parent.right
text: displayName.length > 12 ? displayName.substr(0,12) + "..." : displayName
visible: !fromMe
ToolTip.text: from
ToolTip.visible: ma2.containsMouse
ToolTip.delay: 200
Label { // DISPLAY NAME FOR GROUPS
color: "#FFFFFF"
font.pixelSize: 10 * gcd.themeScale
anchors.right: parent.right
text: displayName.length > 12 ? displayName.substr(0,12) + "..." : displayName
visible: !fromMe
ToolTip.text: from
ToolTip.visible: ma2.containsMouse
ToolTip.delay: 200
MouseArea {
id: ma2
anchors.fill: parent
hoverEnabled: true
}
}
MouseArea {
id: ma2
anchors.fill: parent
hoverEnabled: true
}
}
Image { // ACKNOWLEDGEMENT ICON
id: ack
anchors.right: parent.right
source: root.error != "" ? gcd.assetPath + "fontawesome/regular/window-close.svg" : (root.ackd ? gcd.assetPath + "fontawesome/regular/check-circle.svg" : gcd.assetPath + "fontawesome/regular/hourglass.svg")
height: 10 * gcd.themeScale
sourceSize.height: 10 * gcd.themeScale
visible: fromMe
ToolTip.visible: ma.containsMouse
ToolTip.delay: 200
//: 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"))
Image { // ACKNOWLEDGEMENT ICON
id: ack
anchors.right: parent.right
source: root.error != "" ? gcd.assetPath + "fontawesome/regular/window-close.svg" : (root.ackd ? gcd.assetPath + "fontawesome/regular/check-circle.svg" : gcd.assetPath + "fontawesome/regular/hourglass.svg")
height: 10 * gcd.themeScale
sourceSize.height: 10 * gcd.themeScale
visible: fromMe
ToolTip.visible: ma.containsMouse
ToolTip.delay: 200
//: 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
hoverEnabled: true
}
}
}
}
MouseArea {
id: ma
anchors.fill: parent
hoverEnabled: true
}
}
}
}
TextEdit {
id: copyhelper
@ -188,5 +188,5 @@ Item {
gcd.popup("message copied")
}
}
}
}
}
}

View File

@ -12,22 +12,22 @@ import "../styles"
import "../theme"
Item {
id: root
anchors.fill: parent
width: parent.width
id: root
anchors.fill: parent
width: parent.width
height: profile.height + searchAddText.height + 10
height: profile.height + searchAddText.height + 10
implicitHeight: profile.height + searchAddText.height + 10
property string image
property string nick
property string onion
property string tag
property bool dualPane: false
property string image
property string nick
property string onion
property string tag
property bool dualPane: false
property real logscale: 4 * Math.log10(gcd.themeScale + 1)
onDualPaneChanged: { realignProfile() }
onDualPaneChanged: { realignProfile() }
function realignProfile() {
if (dualPane) {
@ -63,7 +63,7 @@ Item {
}
}
Component.onCompleted: { realignProfile() }
Component.onCompleted: { realignProfile() }
@ -85,10 +85,10 @@ Item {
portraitColor: Theme.portraitOnlineBackgroundColor
badgeContent: Image {// Profle Type
id: profiletype
source: tag == "v1-userPassword" ? gcd.assetPath + "/fontawesome/solid/lock.svg" : gcd.assetPath + "/fontawesome/solid/lock-open.svg"
height: Theme.badgeTextSize * gcd.themeScale
width: height
id: profiletype
source: tag == "v1-userPassword" ? gcd.assetPath + "/fontawesome/solid/lock.svg" : gcd.assetPath + "/fontawesome/solid/lock-open.svg"
height: Theme.badgeTextSize * gcd.themeScale
width: height
}
}
@ -124,34 +124,34 @@ Item {
onClicked: {
}
}
}
}
}
// TODO Remove for new global topbar
Widgets.Button {// BACK BUTTON
id: btnBack
icon: "solid/arrow-circle-left"
anchors.left: parent.left
anchors.leftMargin: 2
anchors.top: parent.top
anchors.topMargin: 2
onClicked: function() {
gcd.selectedProfile = "none"
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
theStack.pane = theStack.emptyPane
}
}
// TODO Remove for new global topbar
Widgets.Button {// BACK BUTTON
id: btnBack
icon: "solid/arrow-circle-left"
anchors.left: parent.left
anchors.leftMargin: 2
anchors.top: parent.top
anchors.topMargin: 2
onClicked: function() {
gcd.selectedProfile = "none"
gcd.reloadProfileList()
parentStack.pane = parentStack.managementPane
theStack.pane = theStack.emptyPane
}
}
TextField {
TextField {
id: searchAddText
anchors.top: profile.bottom
anchors.horizontalCenter: parent.horizontalCenter
style: CwtchTextFieldStyle{ }
style: CwtchTextFieldStyle{ }
width: parent.width - 30
//: ex: "... paste an address here to add a contact ..."
placeholderText: qsTr("paste-address-to-add-contact")
@ -165,19 +165,19 @@ Item {
}
}
Connections {
target: gcd
Connections {
target: gcd
onUpdateMyProfile: function(_nick, _onion, _image, _tag) {
nick = _nick
onion = _onion
image = _image
tag = _tag
}
onUpdateMyProfile: function(_nick, _onion, _image, _tag) {
nick = _nick
onion = _onion
image = _image
tag = _tag
}
/*onTorStatus: function(code, str) {
rectTorStatus.code = code
rectTorStatus.message = str
}*/
}
/*onTorStatus: function(code, str) {
rectTorStatus.code = code
rectTorStatus.message = str
}*/
}
}

View File

@ -7,16 +7,16 @@ import CustomQmlTypes 1.0
import "../theme"
Item {
id: imgProfile
implicitWidth: baseWidth
implicitHeight: baseWidth
id: imgProfile
implicitWidth: baseWidth
implicitHeight: baseWidth
property string source
property alias badgeColor: badge.color
property string source
property alias badgeColor: badge.color
property real logscale: 4 * Math.log10(gcd.themeScale + 1)
property int baseWidth: 78 * logscale
height: 78 * logscale
property real logscale: 4 * Math.log10(gcd.themeScale + 1)
property int baseWidth: 78 * logscale
height: 78 * logscale
property alias portraitBorderColor: mainImage.color
property alias portraitColor: imageInner.color
@ -24,48 +24,48 @@ Item {
property alias badgeContent: badge.content
Rectangle {
id: mainImage
//anchors.leftMargin: baseWidth * 0.1
anchors.horizontalCenter: parent.horizontalCenter
width: baseWidth * 0.8
height: width
Rectangle {
id: mainImage
//anchors.leftMargin: baseWidth * 0.1
anchors.horizontalCenter: parent.horizontalCenter
width: baseWidth * 0.8
height: width
anchors.verticalCenter: parent.verticalCenter
color: Theme.portraitOfflineBorderColor
radius: width / 2
color: Theme.portraitOfflineBorderColor
radius: width / 2
Rectangle {
id: imageInner
width: parent.width - 4
height: width
color: Theme.portraitOfflineBorderColor
radius: width / 2
anchors.centerIn:parent
Rectangle {
id: imageInner
width: parent.width - 4
height: width
color: Theme.portraitOfflineBorderColor
radius: width / 2
anchors.centerIn:parent
Image { // PROFILE IMAGE
id: img
source: gcd.assetPath + imgProfile.source
anchors.fill: parent
fillMode: Image.PreserveAspectFit
visible: false
}
Image { // PROFILE IMAGE
id: img
source: gcd.assetPath + imgProfile.source
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 { // 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
}
}
}
Badge {
Badge {
id: badge
}
}
}

View File

@ -12,21 +12,21 @@ import QtQuick.Controls.Styles 1.4
Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
id: crItem
anchors.left: parent.left
anchors.right: parent.right
height: 78 * logscale + 3
implicitHeight: 78 * logscale + 3 //height
anchors.left: parent.left
anchors.right: parent.right
height: 78 * logscale + 3
implicitHeight: 78 * logscale + 3 //height
property real logscale: 4 * Math.log10(gcd.themeScale + 1)
property string displayName
property alias image: portrait.source
property string handle
property bool isActive
property bool isHover
property string tag // profile version/type
property real logscale: 4 * Math.log10(gcd.themeScale + 1)
property string displayName
property alias image: portrait.source
property string handle
property bool isActive
property bool isHover
property string tag // profile version/type
property alias badgeColor: portrait.badgeColor
property alias portraitBorderColor: portrait.portraitBorderColor
property alias badgeColor: portrait.badgeColor
property alias portraitBorderColor: portrait.portraitBorderColor
property alias portraitColor: portrait.portraitColor
property alias nameColor: cn.color
property alias onionColor: onion.color
@ -38,22 +38,22 @@ Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
property alias content: extraMeta.children
// TODO: should be in ContactRow
property bool blocked
property bool blocked
signal clicked(string handle)
Rectangle { // CONTACT ENTRY BACKGROUND COLOR
id: crRect
anchors.left: parent.left
anchors.right: parent.right
height: crItem.height
width: parent.width
color: isHover ? Theme.backgroundPaneColor : (isActive ? Theme.backgroundPaneColor : Theme.backgroundMainColor)
Rectangle { // CONTACT ENTRY BACKGROUND COLOR
id: crRect
anchors.left: parent.left
anchors.right: parent.right
height: crItem.height
width: parent.width
color: isHover ? Theme.backgroundPaneColor : (isActive ? Theme.backgroundPaneColor : Theme.backgroundMainColor)
Portrait {
id: portrait
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.left: parent.left
anchors.leftMargin: 25 * logscale
}
@ -83,10 +83,10 @@ Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
strikeout: blocked
}
onWidthChanged: {
cn.setTextResize()
onion.setTextResize()
}
onWidthChanged: {
cn.setTextResize()
onion.setTextResize()
}
}
@ -95,40 +95,40 @@ Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
anchors.left: portraitMeta.right
anchors.verticalCenter: parent.verticalCenter
}
}
}
MouseArea { // Full row mouse area triggering onClick
id: buttonMA
anchors.fill: parent
hoverEnabled: true
MouseArea { // Full row mouse area triggering onClick
id: buttonMA
anchors.fill: parent
hoverEnabled: true
onClicked: { crItem.clicked(crItem.handle) }
onClicked: { crItem.clicked(crItem.handle) }
onEntered: {
isHover = true
}
onEntered: {
isHover = true
}
onExited: {
isHover = false
}
}
onExited: {
isHover = false
}
}
Connections { // UPDATE UNREAD MESSAGES COUNTER
target: gcd
Connections { // UPDATE UNREAD MESSAGES COUNTER
target: gcd
onResetMessagePane: function() {
isActive = false
}
onResetMessagePane: function() {
isActive = false
}
onUpdateContactBlocked: function(_handle, _blocked) {
if (handle == _handle) {
blocked = _blocked
blocked = _blocked
}
}
onUpdateContactDisplayName: function(_handle, _displayName) {
if (handle == _handle) {
displayName = _displayName + (blocked == true ? " (blocked)" : "")
displayName = _displayName + (blocked == true ? " (blocked)" : "")
}
}
@ -137,5 +137,5 @@ Item { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
image = _image
}
}
}
}
}

View File

@ -6,7 +6,7 @@ import QtQuick.Layouts 1.3
import "../theme"
ColumnLayout {
id: root
id: root
MouseArea {
anchors.fill: parent
@ -16,30 +16,30 @@ ColumnLayout {
}
}
Flickable { // Profile List
id: sv
clip: true
Layout.minimumHeight: 100
Layout.fillHeight: true
Layout.minimumWidth: parent.width
Layout.maximumWidth: parent.width
contentWidth: colContacts.width
contentHeight: colContacts.height
boundsBehavior: Flickable.StopAtBounds
maximumFlickVelocity: 400
Flickable { // Profile List
id: sv
clip: true
Layout.minimumHeight: 100
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
}
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AlwaysOn
}
ColumnLayout {
id: colContacts
width: root.width
spacing: 0
id: colContacts
width: root.width
spacing: 0
Connections { // ADD/REMOVE CONTACT ENTRIES
target: gcd
Connections { // ADD/REMOVE CONTACT ENTRIES
target: gcd
onAddProfile: function(handle, displayName, image, tag) {
@ -59,50 +59,50 @@ ColumnLayout {
}
}
profilesModel.insert(index,
{
_handle: handle,
_displayName: displayName,
_image: image,
_tag: tag,
_status: 4,
})
}
profilesModel.insert(index,
{
_handle: handle,
_displayName: displayName,
_image: image,
_tag: tag,
_status: 4,
})
}
/*
onRemoveProfile: function(handle) {
for(var i = 0; i < profilesModel.count; i++){
if(profilesModel.get(i)["_handle"] == handle) {
console.log("deleting contact " + profilesModel.get(i)["_handle"])
profilesModel.remove(i)
return
}
}
}*/
onRemoveProfile: function(handle) {
for(var i = 0; i < profilesModel.count; i++){
if(profilesModel.get(i)["_handle"] == handle) {
console.log("deleting contact " + profilesModel.get(i)["_handle"])
profilesModel.remove(i)
return
}
}
}*/
onResetProfileList: function() {
profilesModel.clear()
}
}
onResetProfileList: function() {
profilesModel.clear()
}
}
ListModel { // Profile OBJECTS ARE STORED HERE ...
id: profilesModel
}
ListModel { // Profile OBJECTS ARE STORED HERE ...
id: profilesModel
}
Repeater {
id: profileList
model: profilesModel // ... AND DISPLAYED HERE
delegate: ProfileRow {
handle: _handle
displayName: _displayName
image: _image
blocked: false
Repeater {
id: profileList
model: profilesModel // ... AND DISPLAYED HERE
delegate: ProfileRow {
handle: _handle
displayName: _displayName
image: _image
blocked: false
tag: _tag
}
}
}
}
PortraitRow {
handle: ""
PortraitRow {
handle: ""
displayName: qsTr("add-new-profile-btn")
image: "/fontawesome/regular/user.svg"
tag: ""
@ -110,13 +110,13 @@ ColumnLayout {
portraitColor: Theme.defaultButtonColor
badgeVisible: true
badgeContent: Image {
source: gcd.assetPath + "/fontawesome/solid/plus.svg"
height: Theme.badgeTextSize * gcd.themeScale
width: height
source: gcd.assetPath + "/fontawesome/solid/plus.svg"
height: Theme.badgeTextSize * gcd.themeScale
width: height
}
badgeColor: Theme.portraitOnlineBorderColor
onClicked: function(handle) { profileAddEditPane.reset(); parentStack.pane = parentStack.addEditProfilePane }
}
onClicked: function(handle) { profileAddEditPane.reset(); parentStack.pane = parentStack.addEditProfilePane }
}
}
}
}
}

View File

@ -20,31 +20,31 @@ PortraitRow {
onionColor: Theme.portraitOnlineTextColor
badgeContent: Image {// Profle Type
id: profiletype
source: tag == "v1-userPassword" ? gcd.assetPath + "/fontawesome/solid/lock.svg" : gcd.assetPath + "/fontawesome/solid/lock-open.svg"
height: Theme.badgeTextSize * gcd.themeScale
width: height
id: profiletype
source: tag == "v1-userPassword" ? gcd.assetPath + "/fontawesome/solid/lock.svg" : gcd.assetPath + "/fontawesome/solid/lock-open.svg"
height: Theme.badgeTextSize * gcd.themeScale
width: height
}
Widgets.Button {// Edit BUTTON
id: btnEdit
icon: "solid/user-edit"
id: btnEdit
icon: "solid/user-edit"
anchors.right: parent.right
anchors.right: parent.right
//rectUnread.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 1 * gcd.themeScale
anchors.rightMargin: 20 * gcd.themeScale
height: parent.height * 0.75
//rectUnread.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 1 * gcd.themeScale
anchors.rightMargin: 20 * gcd.themeScale
height: parent.height * 0.75
onClicked: {
profileAddEditPane.load(handle, displayName, tag)
parentStack.pane = parentStack.addEditProfilePane
}
onClicked: {
profileAddEditPane.load(handle, displayName, tag)
parentStack.pane = parentStack.addEditProfilePane
}
}
onClicked: function openClick(handle) {
gcd.broadcast("ResetMessagePane");
@ -53,4 +53,4 @@ PortraitRow {
gcd.loadProfile(handle)
parentStack.pane = parentStack.profilePane
}
}
}

View File

@ -6,22 +6,22 @@ import QtQuick.Controls 2.13
RadioButton {
id: control
property real size: 12
spacing: 0
property real size: 12
spacing: 0
indicator: Rectangle {
width: 16 * gcd.themeScale
height: 16 * gcd.themeScale
anchors.verticalCenter: parent.verticalCenter
radius: 9
border.width: 1
indicator: Rectangle {
width: 16 * gcd.themeScale
height: 16 * gcd.themeScale
anchors.verticalCenter: parent.verticalCenter
radius: 9
border.width: 1
Rectangle {
anchors.fill: parent
visible: control.checked
color: "black"
radius: 9
anchors.margins: 4
}
}
}
Rectangle {
anchors.fill: parent
visible: control.checked
color: "black"
radius: 9
anchors.margins: 4
}
}
}

View File

@ -7,9 +7,9 @@ import QtQuick.Window 2.11
Label {
font.pixelSize: gcd.themeScale * size
wrapMode: Text.WordWrap
color: "#000000"
textFormat: Text.PlainText
property real size: 12
}
font.pixelSize: gcd.themeScale * size
wrapMode: Text.WordWrap
color: "#000000"
textFormat: Text.PlainText
property real size: 12
}

View File

@ -8,62 +8,62 @@ import "../fonts/Twemoji.js" as T
import "." as Widgets
Rectangle { // OVERHEAD BAR ON STACK PANE
id: toolbar
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: 20 * gcd.themeScale + 4
Layout.minimumHeight: height
Layout.maximumHeight: height
color: "#EDEDED"
id: toolbar
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: 20 * gcd.themeScale + 4
Layout.minimumHeight: height
Layout.maximumHeight: height
color: "#EDEDED"
property alias text: lbl.text
property alias aux: btnAux
property alias back: btnBack
property alias membership: btnMembership
property string stack: "profile" // profile(theStack) or management(parentStack)
property alias text: lbl.text
property alias aux: btnAux
property alias back: btnBack
property alias membership: btnMembership
property string stack: "profile" // profile(theStack) or management(parentStack)
Widgets.Button {// BACK BUTTON
id: btnBack
icon: "solid/arrow-circle-left"
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 6
onClicked: {
if (stack == "profile") {
theStack.pane = theStack.emptyPane
} else {
parentStack.pane = parentStack.managementPane
}
}
}
Widgets.Button {// BACK BUTTON
id: btnBack
icon: "solid/arrow-circle-left"
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 6
onClicked: {
if (stack == "profile") {
theStack.pane = theStack.emptyPane
} else {
parentStack.pane = parentStack.managementPane
}
}
}
ScalingLabel { // TEXT
id: lbl
text: "open privacy exec"
ScalingLabel { // TEXT
id: lbl
text: "open privacy exec"
font.family: Fonts.applicationFontRegular.name
font.styleName: "ExtraBold"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
RowLayout {
RowLayout {
anchors.right: parent.right
anchors.rightMargin: 6
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 6
anchors.verticalCenter: parent.verticalCenter
Widgets.Button { // Membership Button
id: btnMembership
icon: "solid/users"
Widgets.Button { // Membership Button
id: btnMembership
icon: "solid/users"
//: View Group Membership
tooltip: qsTr("view-group-membership-tooltip")
}
}
Widgets.Button { // COG BUTTON
id: btnAux
icon: "solid/cog"
}
}
Widgets.Button { // COG BUTTON
id: btnAux
icon: "solid/cog"
}
}
}

View File

@ -13,4 +13,4 @@ TextField {
color: windowItem.cwtch_background_color
border.color: windowItem.cwtch_color
}
}
}

View File

@ -33,11 +33,11 @@ Rectangle {
}
}
Connections {
target: gcd
Connections {
target: gcd
onSupplySettings: function(zoom, newLocale) {
selected = newLocale == locale
}
}
}
onSupplySettings: function(zoom, newLocale) {
selected = newLocale == locale
}
}
}

View File

@ -3,31 +3,31 @@ import QtQuick.Controls 2.4
import QtQuick.Controls.Material 2.0
import QtQuick.Layouts 1.3
Item {
id: root
property alias source: img.source
property int size: 24
property string tooltip: ""
width: size
height: size
signal clicked()
id: root
property alias source: img.source
property int size: 24
property string tooltip: ""
width: size
height: size
signal clicked()
ToolTip.visible: tooltip != "" && ma.containsMouse
ToolTip.text: tooltip
ToolTip.visible: tooltip != "" && ma.containsMouse
ToolTip.text: tooltip
Image {
id: img
width: root.size * (ma.pressed ? 0.5 : 0.8)
height: root.size * (ma.pressed ? 0.5 : 0.8)
anchors.topMargin: ma.pressed ? 2 : 0
anchors.leftMargin: anchors.topMargin
anchors.centerIn: parent
}
Image {
id: img
width: root.size * (ma.pressed ? 0.5 : 0.8)
height: root.size * (ma.pressed ? 0.5 : 0.8)
anchors.topMargin: ma.pressed ? 2 : 0
anchors.leftMargin: anchors.topMargin
anchors.centerIn: parent
}
MouseArea {
id: ma
anchors.fill: root
MouseArea {
id: ma
anchors.fill: root
onClicked: root.clicked()
hoverEnabled: tooltip != ""
}
}
onClicked: root.clicked()
hoverEnabled: tooltip != ""
}
}

8
quality.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/sh
# go get cwtch.im/ui/cmd/qmlfmt
cd qml
find -iname "*.qml" | xargs qmlfmt
cd ..