Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8865afa4db |
@@ -13,4 +13,3 @@ Makefile
|
||||
*_qml.cpp
|
||||
*_qmlcache.qrc
|
||||
sandbox/qmlcache_loader.cpp
|
||||
doc/html
|
||||
@@ -1,14 +1,3 @@
|
||||
<a name=""></a>
|
||||
## 0.24.0 (2022-02-14)
|
||||
|
||||
|
||||
#### Features
|
||||
|
||||
* **StatusListItem:** add highlighted property ([5780f183](5780f183))
|
||||
* **StatusQ.Components:** Adding StatusWizardSteper component ([b7d6554b](b7d6554b), closes [#522](522))
|
||||
|
||||
|
||||
|
||||
<a name=""></a>
|
||||
## Version 0.23.0 (2022-02-08)
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -351,30 +351,18 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
nickName: "This is an example"
|
||||
userName: "annabelle"
|
||||
chatKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
|
||||
trustIndicator: StatusMemberListItem.TrustedType.Verified
|
||||
isMutualContact: true
|
||||
image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
|
||||
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||
image.isIdenticon: true
|
||||
isOnline: true
|
||||
ringSettings.ringSpecModel:
|
||||
ListModel {
|
||||
ListElement {colorId: 13; segmentLength: 5}
|
||||
ListElement {colorId: 31; segmentLength: 5}
|
||||
ListElement {colorId: 10; segmentLength: 1}
|
||||
ListElement {colorId: 2; segmentLength: 5}
|
||||
ListElement {colorId: 26; segmentLength: 2}
|
||||
ListElement {colorId: 19; segmentLength: 4}
|
||||
ListElement {colorId: 28; segmentLength: 3}
|
||||
}
|
||||
ringSettings.distinctiveColors: Theme.palette.identiconRingColors
|
||||
ringSettings.totalRingUnits: 25
|
||||
}
|
||||
|
||||
StatusMemberListItem {
|
||||
nickName: "carmen.eth"
|
||||
isOnline: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
trustIndicator: StatusMemberListItem.TrustedType.Untrustworthy
|
||||
}
|
||||
|
||||
StatusMemberListItem {
|
||||
|
||||
@@ -41,8 +41,7 @@ ListView {
|
||||
}
|
||||
messageText: model.message
|
||||
hasMention: model.hasMention
|
||||
isMutualContact: model.isMutualContact
|
||||
trustIndicator: model.trustIndicator
|
||||
contactType: model.contactType
|
||||
isPinned: model.isPinned
|
||||
pinnedBy: model.pinnedBy
|
||||
hasExpired: model.hasExpired
|
||||
|
||||
@@ -170,6 +170,27 @@ Page {
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
StatusBadge {
|
||||
id: statusBadge
|
||||
width: 15
|
||||
height: 15
|
||||
anchors.left: contactImage.right
|
||||
anchors.leftMargin: -8
|
||||
anchors.bottom: contactImage.bottom
|
||||
border.width: 3
|
||||
border.color: Theme.palette.statusAppNavBar.backgroundColor
|
||||
color: {
|
||||
if (model.onlineStatus === 1)
|
||||
return Theme.palette.successColor1;
|
||||
else if (model.onlineStatus === 2)
|
||||
return Theme.palette.pinColor1;
|
||||
else if (model.onlineStatus === 3)
|
||||
return Theme.palette.dangerColor1;
|
||||
|
||||
return "transparent"
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
|
||||
@@ -266,9 +266,6 @@ StatusAppThreePanelLayout {
|
||||
image.source: model.source
|
||||
image.isIdenticon: model.isIdenticon
|
||||
isOnline: model.isOnline
|
||||
ringSettings.ringSpecModel: model.ringSpecModel
|
||||
ringSettings.distinctiveColors: Theme.palette.identiconRingColors
|
||||
ringSettings.totalRingUnits: model.totalRingUnits
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,8 +497,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f5789"
|
||||
isMutualContact: true
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
contactType: 2
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: false
|
||||
@@ -526,8 +525,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f2333"
|
||||
isMutualContact: true
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
|
||||
contactType: 3
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: false
|
||||
@@ -554,8 +552,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAkUlEQVR4nOzYwQmDQBQG4SSkl3SQyizDyuzAavTi0cPK8sPwM9/Rw8rw4KH7eZUwhMYQGkNoDKGpCfmmDl63/bh7vvx/78T7aiZiCI0hNMMbJL2FZs+vmYghNIbQTG+cp9smtf1qJmIIjSEKqZmIITSG0Azfa6W/qfxDvBhCY4hCaiZiCI0hNIbQGEJzBgAA///3pSBjX42sYAAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f2333"
|
||||
isMutualContact: true
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
|
||||
contactType: 3
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: false
|
||||
@@ -582,8 +579,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f6789"
|
||||
isMutualContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
contactType: 4
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: false
|
||||
@@ -611,8 +607,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: true
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
contactType: 0
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: false
|
||||
@@ -640,8 +635,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
contactType: 0
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: false
|
||||
@@ -669,8 +663,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
contactType: 0
|
||||
hasMention: true
|
||||
editMode: false
|
||||
isReply: false
|
||||
@@ -699,8 +692,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
contactType: 0
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: true
|
||||
@@ -729,8 +721,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
contactType: 0
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: true
|
||||
@@ -759,8 +750,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
contactType: 0
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: true
|
||||
@@ -789,8 +779,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
contactType: 0
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: true
|
||||
@@ -818,8 +807,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
|
||||
contactType: 0
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: false
|
||||
@@ -846,8 +834,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: true
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
contactType: 0
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: false
|
||||
@@ -874,8 +861,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
|
||||
isMutualContact: true
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
contactType: 0
|
||||
hasMention: false
|
||||
editMode: false
|
||||
isReply: false
|
||||
@@ -897,69 +883,44 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
nickName: "This is an example"
|
||||
userName: "annabelle"
|
||||
chatKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
|
||||
trustIndicator: StatusMemberListItem.TrustedType.Verified
|
||||
isMutualContact: true
|
||||
isOnline: true
|
||||
source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
|
||||
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||
isIdenticon: true
|
||||
totalRingUnits: 25
|
||||
ringSpecModel: [ ListElement {colorId: 13; segmentLength: 5},
|
||||
ListElement {colorId: 31; segmentLength: 5},
|
||||
ListElement {colorId: 10; segmentLength: 1},
|
||||
ListElement {colorId: 2; segmentLength: 5},
|
||||
ListElement {colorId: 26; segmentLength: 2},
|
||||
ListElement {colorId: 19; segmentLength: 4},
|
||||
ListElement {colorId: 28; segmentLength: 3} ]
|
||||
}
|
||||
ListElement {
|
||||
nickName: "carmen.eth"
|
||||
userName: ""
|
||||
chatKey: ""
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
trustIndicator: StatusMemberListItem.TrustedType.Untrustworthy
|
||||
isMutualContact: false
|
||||
isOnline: false
|
||||
source: ""
|
||||
isIdenticon: false
|
||||
isIdenticon: false
|
||||
}
|
||||
ListElement {
|
||||
nickName: "This girl I know from work"
|
||||
userName: "annabelle"
|
||||
chatKey: ""
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
trustIndicator: StatusMemberListItem.TrustedType.None
|
||||
isMutualContact: false
|
||||
isOnline: true
|
||||
source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDK
|
||||
ExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
totalRingUnits: 25
|
||||
ringSpecModel: [ ListElement {colorId: 11; segmentLength: 1},
|
||||
ListElement {colorId: 23; segmentLength: 5},
|
||||
ListElement {colorId: 23; segmentLength: 5},
|
||||
ListElement {colorId: 10; segmentLength: 4},
|
||||
ListElement {colorId: 15; segmentLength: 3},
|
||||
ListElement {colorId: 26; segmentLength: 2},
|
||||
ListElement {colorId: 29; segmentLength: 5} ]
|
||||
}
|
||||
ListElement {
|
||||
nickName: "Mark Cuban"
|
||||
userName: "annabelle"
|
||||
chatKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
trustIndicator: StatusMemberListItem.TrustedType.Untrustworthy
|
||||
isMutualContact: true
|
||||
isOnline: false
|
||||
source: ""
|
||||
isIdenticon: false
|
||||
totalRingUnits: 25
|
||||
ringSpecModel: [ ListElement {colorId: 0; segmentLength: 1},
|
||||
ListElement {colorId: 28; segmentLength: 1},
|
||||
ListElement {colorId: 31; segmentLength: 1},
|
||||
ListElement {colorId: 22; segmentLength: 4},
|
||||
ListElement {colorId: 28; segmentLength: 3},
|
||||
ListElement {colorId: 27; segmentLength: 5},
|
||||
ListElement {colorId: 7; segmentLength: 5},
|
||||
ListElement {colorId: 13; segmentLength: 1},
|
||||
ListElement {colorId: 25; segmentLength: 4}]
|
||||
source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
|
||||
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||
isIdenticon: true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
@@ -30,10 +30,8 @@
|
||||
\li \l{StatusSlider}
|
||||
\li \l{StatusSelect}
|
||||
\li \l{StatusBaseInput}
|
||||
\li \l{StatusIdenticonRing}
|
||||
\li \l{StatusInput}
|
||||
\li \l{StatusPickerButton}
|
||||
\li \l{StatusPinInput}
|
||||
\li \l{StatusProgressBar}
|
||||
\li \l{StatusPasswordStrengthIndicator}
|
||||
\li \l{StatusSwitchTabButton}
|
||||
@@ -41,7 +39,5 @@
|
||||
\li \l{StatusSelectableText}
|
||||
\li \l{StatusWalletColorButton}
|
||||
\li \l{StatusWalletColorSelect}
|
||||
\li \l{StatusRegularExpressionValidator}
|
||||
\li \l{StatusIntValidator}
|
||||
\endlist
|
||||
*/
|
||||
@@ -15,7 +15,6 @@
|
||||
\li \l{StatusIcon}
|
||||
\li \l{StatusIconBackgroundSettings}
|
||||
\li \l{StatusIconSettings}
|
||||
\li \l{StatusIdenticonRingSettings}
|
||||
\li \l{StatusImageSettings}
|
||||
\li \l{StatusModalHeaderSettings}
|
||||
\li \l{StatusTooltipSettings}
|
||||
@@ -5,16 +5,16 @@ url = https://github.com/status-im/StatusQ
|
||||
|
||||
#These are set implictly by qdoc as well, but only with these the module header can be found
|
||||
includepaths = -I . \
|
||||
-I $PWD/../src/StatusQ
|
||||
-I $PWD/../../src/StatusQ
|
||||
|
||||
imagedirs = src/images
|
||||
sourcedirs += src \
|
||||
$PWD/../src/StatusQ/Components \
|
||||
$PWD/../src/StatusQ/Controls \
|
||||
$PWD/../src/StatusQ/Core \
|
||||
$PWD/../src/StatusQ/Layout \
|
||||
$PWD/../src/StatusQ/Platform \
|
||||
$PWD/../src/StatusQ/Popups \
|
||||
$PWD/../../src/StatusQ/Components \
|
||||
$PWD/../../src/StatusQ/Controls \
|
||||
$PWD/../../src/StatusQ/Core \
|
||||
$PWD/../../src/StatusQ/Layout \
|
||||
$PWD/../../src/StatusQ/Platform \
|
||||
$PWD/../../src/StatusQ/Popups \
|
||||
|
||||
sources.fileextensions = "*.cpp *.qdoc *.qml"
|
||||
|
||||
@@ -229,11 +229,6 @@ StatusWindow {
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusPinInput"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusListSectionHeadline { text: "StatusQ.Components" }
|
||||
StatusNavigationListItem {
|
||||
title: "StatusAddress"
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
|
||||
Column {
|
||||
id: root
|
||||
spacing: 25
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
|
||||
// PIN input that accepts only numbers
|
||||
StatusBaseText {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: Theme.palette.directColor1
|
||||
text: "Enter Keycard PIN"
|
||||
font.pixelSize: 30
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
StatusPinInput {
|
||||
id: numbersPinInput
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
validator: StatusIntValidator{bottom: 0; top: 999999;}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: Theme.palette.dangerColor1
|
||||
text: "Only numbers allowed"
|
||||
font.pixelSize: 16
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: Theme.palette.directColor1
|
||||
text: "Introduced PIN: " + numbersPinInput.pinInput
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
// PIN input that accepts input depending on the regular expression definition
|
||||
StatusBaseText {
|
||||
topPadding: 100
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: Theme.palette.directColor1
|
||||
text: "Enter another Keycard PIN"
|
||||
font.pixelSize: 30
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
StatusPinInput {
|
||||
id: regexPinInput
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
validator: StatusRegularExpressionValidator { regularExpression: /[0-9A-Za-z@]+/ }
|
||||
circleDiameter: 22
|
||||
circleSpacing: 22
|
||||
pinLen: 7
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: Theme.palette.dangerColor1
|
||||
text: "Only alphanumeric characters and '@' allowed"
|
||||
font.pixelSize: 16
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: Theme.palette.directColor1
|
||||
text: "Introduced PIN: " + regexPinInput.pinInput
|
||||
font.pixelSize: 12
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
make clean
|
||||
if [[ $OSTYPE == 'darwin'* ]]
|
||||
then
|
||||
qmake sandbox.pro -spec macx-clang CONFIG+=debug CONFIG+=x86_64 && /usr/bin/make qmake_all
|
||||
else
|
||||
qmake sandbox.pro CONFIG+=debug CONFIG+=x86_64 && /usr/bin/make qmake_all
|
||||
fi
|
||||
make
|
||||
qmake sandbox.pro -spec macx-clang CONFIG+=debug CONFIG+=x86_64 && /usr/bin/make qmake_all
|
||||
make
|
||||
|
||||
|
||||
@@ -101,7 +101,6 @@ Column {
|
||||
muted: model.muted
|
||||
hasUnreadMessages: model.hasUnreadMessages
|
||||
notificationsCount: model.notificationsCount
|
||||
highlightWhenCreated: model.highlight
|
||||
selected: model.active
|
||||
icon.color: model.color
|
||||
image.isIdenticon: model.isIdenticon
|
||||
@@ -109,8 +108,6 @@ Column {
|
||||
|
||||
sensor.cursorShape: dragSensor.cursorShape
|
||||
onClicked: {
|
||||
highlightWhenCreated = false
|
||||
|
||||
if (mouse.button === Qt.RightButton && !!statusChatList.popupMenu) {
|
||||
statusChatListItem.highlighted = true
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ Rectangle {
|
||||
}
|
||||
property int type: StatusChatListItem.Type.PublicChat
|
||||
property bool highlighted: false
|
||||
property bool highlightWhenCreated: false
|
||||
property bool selected: false
|
||||
property bool dragged: false
|
||||
property alias sensor: sensor
|
||||
@@ -146,14 +145,12 @@ Rectangle {
|
||||
statusChatListItem.notificationsCount > 0 ||
|
||||
statusChatListItem.selected ||
|
||||
statusChatListItem.highlighted ||
|
||||
statusChatListItem.highlightWhenCreated ||
|
||||
hoverHander.hovered ||
|
||||
statusBadge.visible ? Theme.palette.directColor1 : Theme.palette.directColor4
|
||||
}
|
||||
font.weight: !statusChatListItem.muted &&
|
||||
(statusChatListItem.hasUnreadMessages ||
|
||||
statusChatListItem.notificationsCount > 0 ||
|
||||
statusChatListItem.highlightWhenCreated ||
|
||||
statusBadge.visible) ? Font.Bold : Font.Medium
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
Row {
|
||||
id: root
|
||||
|
||||
property bool isMutualContact: false
|
||||
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
|
||||
property StatusIconSettings mutualConnectionIcon: StatusIconSettings {
|
||||
name: "tiny/tiny-contact"
|
||||
color: Theme.palette.indirectColor1
|
||||
width: dummyImage.width
|
||||
height: dummyImage.height
|
||||
background: StatusIconBackgroundSettings {
|
||||
width: 10
|
||||
height: 10
|
||||
color: Theme.palette.primaryColor1
|
||||
}
|
||||
// Only used to get implicit width and height from the actual image
|
||||
property Image dummyImage: Image {
|
||||
source: mutualConnectionIcon.name ? "../../assets/img/icons/" + mutualConnectionIcon.name + ".svg": ""
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
|
||||
property StatusIconSettings trustContactIcon: StatusIconSettings {
|
||||
// None and Untrustworthy types, same aspect (Icon will not be visible in case of None type):
|
||||
name: root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified ? "tiny/tiny-checkmark" : "tiny/subtract"
|
||||
color: Theme.palette.indirectColor1
|
||||
width: dummyImage.width
|
||||
height: dummyImage.height
|
||||
background: StatusIconBackgroundSettings {
|
||||
width: 10
|
||||
height: 10
|
||||
color: root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified ? Theme.palette.primaryColor1 : Theme.palette.dangerColor1
|
||||
}
|
||||
// Only used to get implicit width and height from the actual image
|
||||
property Image dummyImage: Image {
|
||||
source: trustContactIcon.name ? "../../assets/img/icons/" + trustContactIcon.name + ".svg": ""
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
|
||||
enum TrustedType {
|
||||
None, //0
|
||||
Verified, //1
|
||||
Untrustworthy //2
|
||||
}
|
||||
|
||||
spacing: 4
|
||||
visible: root.isMutualContact || (root.trustIndicator !== StatusContactVerificationIcons.TrustedType.None)
|
||||
|
||||
StatusRoundIcon {
|
||||
visible: root.isMutualContact
|
||||
icon.name: root.mutualConnectionIcon.name
|
||||
icon.width: root.mutualConnectionIcon.width
|
||||
icon.height: root.mutualConnectionIcon.height
|
||||
icon.rotation: root.mutualConnectionIcon.rotation
|
||||
icon.color: root.mutualConnectionIcon.color
|
||||
icon.background.color: root.mutualConnectionIcon.background.color
|
||||
icon.background.width: root.mutualConnectionIcon.background.width
|
||||
icon.background.height: root.mutualConnectionIcon.background.height
|
||||
}
|
||||
|
||||
StatusRoundIcon {
|
||||
visible: root.trustIndicator !== StatusContactVerificationIcons.TrustedType.None
|
||||
icon.name: root.trustContactIcon.name
|
||||
icon.width: root.trustContactIcon.width
|
||||
icon.height: root.trustContactIcon.height
|
||||
icon.rotation: root.trustContactIcon.rotation
|
||||
icon.color: root.trustContactIcon.color
|
||||
icon.background.color: root.trustContactIcon.background.color
|
||||
icon.background.width: root.trustContactIcon.background.width
|
||||
icon.background.height: root.trustContactIcon.background.height
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,8 @@ Rectangle {
|
||||
property string titleId: ""
|
||||
property string title: ""
|
||||
property string titleAsideText: ""
|
||||
property bool titleIcon1Visible
|
||||
property bool titleIcon2Visible
|
||||
property string subTitle: ""
|
||||
property string tertiaryTitle: ""
|
||||
property string label: ""
|
||||
@@ -20,7 +22,6 @@ Rectangle {
|
||||
property real rightPadding: 16
|
||||
property bool enabled: true
|
||||
property bool highlighted: false
|
||||
property bool propagateTitleClicks: true
|
||||
property int type: StatusListItem.Type.Primary
|
||||
property list<Item> components
|
||||
|
||||
@@ -51,10 +52,31 @@ Rectangle {
|
||||
height: 40
|
||||
isIdenticon: false
|
||||
}
|
||||
property StatusIdenticonRingSettings ringSettings: StatusIdenticonRingSettings {
|
||||
totalRingUnits: 1
|
||||
initalAngleRad: 0
|
||||
ringPxSize: 1.5
|
||||
property StatusIconSettings titleIcon1: StatusIconSettings {
|
||||
width: dummyImage.width
|
||||
height: dummyImage.height
|
||||
background: StatusIconBackgroundSettings {
|
||||
width: 10
|
||||
height: 10
|
||||
}
|
||||
// Only used to get implicit width and height from the actual image
|
||||
property Image dummyImage: Image {
|
||||
source: titleIcon1.name ? "../../assets/img/icons/" + titleIcon1.name + ".svg": ""
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
property StatusIconSettings titleIcon2: StatusIconSettings {
|
||||
width: dummyImage.width
|
||||
height: dummyImage.height
|
||||
background: StatusIconBackgroundSettings {
|
||||
width: 10
|
||||
height: 10
|
||||
}
|
||||
// Only used to get implicit width and height from the actual image
|
||||
property Image dummyImage: Image {
|
||||
source: titleIcon2.name ? "../../assets/img/icons/" + titleIcon2.name + ".svg": ""
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
|
||||
property alias sensor: sensor
|
||||
@@ -62,7 +84,6 @@ Rectangle {
|
||||
property alias statusListItemIcon: iconOrImage
|
||||
property alias statusListItemTitle: statusListItemTitle
|
||||
property alias statusListItemTitleAside: statusListItemTitleAsideText
|
||||
property alias statusListItemTitleIcons: titleIconsRow
|
||||
property alias statusListItemTitleArea: statusListItemTitleArea
|
||||
property alias statusListItemSubTitle: statusListItemSubTitle
|
||||
property alias statusListItemTertiaryTitle: statusListItemTertiaryTitle
|
||||
@@ -129,23 +150,14 @@ Rectangle {
|
||||
!!statusListItem.icon.name ||
|
||||
!!statusListItem.image.source.toString()
|
||||
badge.border.color: statusListItem.color
|
||||
ringSettings: statusListItem.ringSettings
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusListItemTitleArea
|
||||
|
||||
function getStatusListItemTitleAnchorsRight() {
|
||||
let isIconsRowVisible = false
|
||||
if(titleIconsRow.item) {
|
||||
isIconsRowVisible = true//titleIconsRow.item.visible
|
||||
}
|
||||
return !statusListItem.titleAsideText && !isIconsRowVisible ? statusListItemTitleArea.right : undefined
|
||||
}
|
||||
|
||||
anchors.left: iconOrImage.active ? iconOrImage.right : parent.left
|
||||
anchors.right: statusListItemLabel.visible ? statusListItemLabel.left : statusListItemComponentsSlot.left
|
||||
anchors.leftMargin: iconOrImage.active ? 16 : statusListItem.leftPadding
|
||||
anchors.right: statusListItemLabel.visible ?
|
||||
statusListItemLabel.left : statusListItemComponentsSlot.left
|
||||
anchors.leftMargin: statusListItem.leftPadding
|
||||
anchors.rightMargin: statusListItem.rightPadding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
height: childrenRect.height
|
||||
@@ -157,7 +169,8 @@ Rectangle {
|
||||
height: visible ? contentHeight : 0
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
anchors.left: parent.left
|
||||
anchors.right: !statusListItem.titleAsideText && !titleIconsRow.sourceComponent ? parent.right : undefined
|
||||
anchors.right: !statusListItem.titleAsideText && !statusListItem.titleIcon1Visible && !statusListItem.titleIcon2Visible
|
||||
? parent.right : undefined
|
||||
color: {
|
||||
if (!statusListItem.enabled) {
|
||||
return Theme.palette.baseColor1
|
||||
@@ -176,7 +189,7 @@ Rectangle {
|
||||
anchors.fill: parent
|
||||
cursorShape: containsMouse? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
hoverEnabled: true
|
||||
propagateComposedEvents: statusListItem.propagateTitleClicks
|
||||
propagateComposedEvents: true
|
||||
onClicked: {
|
||||
statusListItem.titleClicked(statusListItem.titleId)
|
||||
mouse.accepted = false
|
||||
@@ -195,12 +208,37 @@ Rectangle {
|
||||
visible: !!statusListItem.titleAsideText
|
||||
}
|
||||
|
||||
Loader {
|
||||
Row {
|
||||
id: titleIconsRow
|
||||
spacing: 4
|
||||
anchors.left: !statusListItem.titleAsideText ? statusListItemTitle.right : statusListItemTitleAsideText.right
|
||||
anchors.verticalCenter: statusListItemTitle.verticalCenter
|
||||
anchors.leftMargin: 4
|
||||
}
|
||||
anchors.leftMargin: titleIconsRow.spacing
|
||||
|
||||
StatusRoundIcon {
|
||||
visible: statusListItem.titleIcon1Visible
|
||||
icon.name: statusListItem.titleIcon1.name
|
||||
icon.width: statusListItem.titleIcon1.width
|
||||
icon.height: statusListItem.titleIcon1.height
|
||||
icon.rotation: statusListItem.titleIcon1.rotation
|
||||
icon.color: statusListItem.titleIcon1.color
|
||||
icon.background.color: statusListItem.titleIcon1.background.color
|
||||
icon.background.width: statusListItem.titleIcon1.background.width
|
||||
icon.background.height: statusListItem.titleIcon1.background.height
|
||||
}
|
||||
|
||||
StatusRoundIcon {
|
||||
visible: statusListItem.titleIcon2Visible
|
||||
icon.name: statusListItem.titleIcon2.name
|
||||
icon.width: statusListItem.titleIcon2.width
|
||||
icon.height: statusListItem.titleIcon2.height
|
||||
icon.rotation: statusListItem.titleIcon2.rotation
|
||||
icon.color: statusListItem.titleIcon2.color
|
||||
icon.background.color: statusListItem.titleIcon2.background.color
|
||||
icon.background.width: statusListItem.titleIcon2.background.width
|
||||
icon.background.height: statusListItem.titleIcon2.background.height
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: statusListItemSubTitle
|
||||
@@ -246,6 +284,7 @@ Rectangle {
|
||||
visible: !!statusListItem.label
|
||||
}
|
||||
|
||||
|
||||
Row {
|
||||
id: statusListItemComponentsSlot
|
||||
anchors.right: parent.right
|
||||
|
||||
@@ -10,9 +10,15 @@ StatusListItem {
|
||||
property string userName: ""
|
||||
property string chatKey: ""
|
||||
property bool isMutualContact: false
|
||||
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
property var trustIndicator: StatusMemberListItem.TrustedType.None
|
||||
property bool isOnline: false
|
||||
|
||||
enum TrustedType {
|
||||
None, //0
|
||||
Verified, //1
|
||||
Untrustworthy //2
|
||||
}
|
||||
|
||||
// Subtitle composition:
|
||||
function composeSubtitile() {
|
||||
var compose = ""
|
||||
@@ -36,10 +42,8 @@ StatusListItem {
|
||||
|
||||
// root object settings:
|
||||
title: root.nickName
|
||||
statusListItemTitleIcons.sourceComponent: StatusContactVerificationIcons {
|
||||
isMutualContact: root.isMutualContact
|
||||
trustIndicator: root.trustIndicator
|
||||
}
|
||||
titleIcon1Visible: root.isMutualContact
|
||||
titleIcon2Visible: root.trustIndicator !== StatusMemberListItem.TrustedType.None
|
||||
subTitle: composeSubtitile()
|
||||
statusListItemSubTitle.font.pixelSize: 10
|
||||
icon.isLetterIdenticon: !root.image.source.toString()
|
||||
@@ -47,7 +51,7 @@ StatusListItem {
|
||||
statusListItemIcon.badge.color: root.isOnline ? Theme.palette.successColor1 : Theme.palette.baseColor1
|
||||
color: sensor.containsMouse ? Theme.palette.baseColor2 : Theme.palette.baseColor4
|
||||
|
||||
// Default sizes / positions by design
|
||||
// Default sizes/positions by design
|
||||
implicitWidth: 256
|
||||
implicitHeight: Math.max(56, statusListItemTitleArea.height + leftPadding)
|
||||
leftPadding: 8
|
||||
@@ -60,4 +64,13 @@ StatusListItem {
|
||||
statusListItemIcon.badge.border.width: 2
|
||||
statusListItemIcon.badge.implicitHeight: 12 // 8 px + 2 px * 2 borders
|
||||
statusListItemIcon.badge.implicitWidth: 12 // 8 px + 2 px * 2 borders
|
||||
|
||||
// Trusted type icons definition:
|
||||
titleIcon1.name: "tiny/tiny-contact"
|
||||
titleIcon1.color: Theme.palette.indirectColor1
|
||||
titleIcon1.background.color: Theme.palette.primaryColor1
|
||||
// None and Untrustworthy types, same aspect (Icon will not be visible in case of None type):
|
||||
titleIcon2.name: trustIndicator === StatusMemberListItem.TrustedType.Verified ? "tiny/tiny-checkmark" : "tiny/subtract"
|
||||
titleIcon2.color: Theme.palette.indirectColor1
|
||||
titleIcon2.background.color: trustIndicator === StatusMemberListItem.TrustedType.Verified ? Theme.palette.primaryColor1 : Theme.palette.dangerColor1
|
||||
}
|
||||
|
||||
@@ -21,6 +21,14 @@ Rectangle {
|
||||
Invitation = 7
|
||||
}
|
||||
|
||||
enum ContactType {
|
||||
STANDARD = 0,
|
||||
RENAME = 1,
|
||||
CONTACT = 2,
|
||||
VERIFIED = 3,
|
||||
UNTRUSTWORTHY = 4
|
||||
}
|
||||
|
||||
property alias messageHeader: messageHeader
|
||||
property alias quickActions:quickActionsPanel.quickActions
|
||||
property alias statusChatInput: editComponent.inputComponent
|
||||
@@ -100,8 +108,11 @@ Rectangle {
|
||||
displayName: messageDetails.displayName
|
||||
secondaryName: messageDetails.secondaryName
|
||||
tertiaryDetail: messageDetails.chatID
|
||||
isMutualContact: messageDetails.isMutualContact
|
||||
trustIndicator: messageDetails.trustIndicator
|
||||
icon1.name: messageDetails.contactType === StatusMessage.ContactType.CONTACT ? "tiny/tiny-contact" : ""
|
||||
icon2.name: messageDetails.contactType === StatusMessage.ContactType.VERIFIED ? "tiny/tiny-checkmark" :
|
||||
messageDetails.contactType === StatusMessage.ContactType.UNTRUSTWORTHY ? "tiny/subtract": ""
|
||||
icon2.background.color: messageDetails.contactType === StatusMessage.ContactType.UNTRUSTWORTHY ? Theme.palette.dangerColor1 : Theme.palette.primaryColor1
|
||||
icon2.color: Theme.palette.indirectColor1
|
||||
resendText: statusMessage.resendText
|
||||
showResendButton: messageDetails.hasExpired && messageDetails.amISender
|
||||
onClicked: statusMessage.senderNameClicked()
|
||||
|
||||
@@ -17,13 +17,12 @@ QtObject {
|
||||
property string messageText: ""
|
||||
property int contentType: 0
|
||||
property string messageContent: ""
|
||||
property bool isMutualContact: false
|
||||
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
property int contactType: 0
|
||||
property bool hasMention: false
|
||||
property bool isPinned: false
|
||||
property string pinnedBy: ""
|
||||
property bool hasExpired: false
|
||||
property string timestamp: ""
|
||||
property string timestamp: ""
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import QtQuick 2.13
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
Loader {
|
||||
id: statusSmartIdenticon
|
||||
|
||||
property string name: ""
|
||||
property int dZ: 100
|
||||
|
||||
// Badge color properties must be set if badgeItem.visible = true
|
||||
property alias badge: statusBadge
|
||||
@@ -22,12 +20,6 @@ Loader {
|
||||
height: 40
|
||||
}
|
||||
|
||||
property StatusIdenticonRingSettings ringSettings: StatusIdenticonRingSettings {
|
||||
totalRingUnits: 1
|
||||
initalAngleRad: 0
|
||||
ringPxSize: 1.5
|
||||
}
|
||||
|
||||
sourceComponent: statusSmartIdenticon.icon.isLetterIdenticon ? letterIdenticon :
|
||||
!!statusSmartIdenticon.image.source.toString() ? roundedImage :
|
||||
!!statusSmartIdenticon.icon.name.toString() ? roundedIcon : letterIdenticon
|
||||
@@ -87,13 +79,6 @@ Loader {
|
||||
}
|
||||
}
|
||||
|
||||
// Next components are painted above main sourceComponent
|
||||
StatusIdenticonRing {
|
||||
settings: statusSmartIdenticon.ringSettings
|
||||
anchors.fill: parent
|
||||
z: statusSmartIdenticon.dZ/2
|
||||
}
|
||||
|
||||
// State component
|
||||
StatusBadge {
|
||||
id: statusBadge
|
||||
@@ -103,6 +88,6 @@ Loader {
|
||||
border.width: 3
|
||||
implicitHeight: 15
|
||||
implicitWidth: 15
|
||||
z: statusSmartIdenticon.dZ
|
||||
z: 100
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,21 +19,17 @@ Item {
|
||||
property ListModel namesModel: ListModel { }
|
||||
|
||||
function find(model, criteria) {
|
||||
for (var i = 0; i < model.count; ++i) if (criteria(model.get(i))) return model.get(i);
|
||||
return null;
|
||||
for (var i = 0; i < model.count; ++i) if (criteria(model.get(i))) return model.get(i);
|
||||
return null;
|
||||
}
|
||||
|
||||
function insertTag(name, id) {
|
||||
if (!find(namesModel, function(item) { return item.publicId === id }) && namesModel.count < root.nameCountLimit) {
|
||||
namesModel.insert(namesModel.count, {"name": name, "publicId": id});
|
||||
addMember(id);
|
||||
edit.clear();
|
||||
}
|
||||
}
|
||||
|
||||
signal addMember(string memberId)
|
||||
signal removeMember(string memberId)
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: 8
|
||||
@@ -51,53 +47,47 @@ Item {
|
||||
text: root.toLabelText
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.fillWidth: true
|
||||
ListView {
|
||||
id: namesList
|
||||
Layout.preferredWidth: (count >= 5) ? (parent.width - warningTextLabel.width - 30) : childrenRect.width
|
||||
implicitHeight: 30
|
||||
visible: (count > 0)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: (namesList.count > 0)
|
||||
contentWidth: namesList.contentWidth
|
||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
model: namesModel
|
||||
orientation: ListView.Horizontal
|
||||
spacing: 8
|
||||
clip: true
|
||||
ListView {
|
||||
id: namesList
|
||||
anchors.fill: parent
|
||||
model: namesModel
|
||||
orientation: ListView.Horizontal
|
||||
spacing: 8
|
||||
onContentWidthChanged: {
|
||||
positionViewAtEnd();
|
||||
onWidthChanged: {
|
||||
positionViewAtEnd();
|
||||
}
|
||||
|
||||
delegate: Rectangle {
|
||||
id: nameDelegate
|
||||
width: (nameText.contentWidth + 34)
|
||||
height: 30
|
||||
color: mouseArea.containsMouse ? Theme.palette.miscColor1 : Theme.palette.primaryColor1
|
||||
radius: 8
|
||||
StatusBaseText {
|
||||
id: nameText
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 8
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Theme.palette.indirectColor1
|
||||
text: name
|
||||
}
|
||||
delegate: Rectangle {
|
||||
id: nameDelegate
|
||||
width: (nameText.contentWidth + 34)
|
||||
height: 30
|
||||
color: mouseArea.containsMouse ? Theme.palette.miscColor1 : Theme.palette.primaryColor1
|
||||
radius: 8
|
||||
StatusBaseText {
|
||||
id: nameText
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 8
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Theme.palette.indirectColor1
|
||||
text: name
|
||||
}
|
||||
StatusIcon {
|
||||
anchors.left: nameText.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Theme.palette.indirectColor1
|
||||
icon: "close"
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
removeMember(publicId);
|
||||
namesModel.remove(index, 1);
|
||||
}
|
||||
StatusIcon {
|
||||
anchors.left: nameText.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Theme.palette.indirectColor1
|
||||
icon: "close"
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
namesModel.remove(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,8 +106,7 @@ Item {
|
||||
color: Theme.palette.directColor1
|
||||
Keys.onPressed: {
|
||||
if ((event.key === Qt.Key_Backspace || event.key === Qt.Key_Escape)
|
||||
&& getText(cursorPosition, (cursorPosition-1)) === "") {
|
||||
removeMember(namesModel.get(namesList.count-1).publicId);
|
||||
&& getText(cursorPosition, (cursorPosition-1)) === "") {
|
||||
namesModel.remove((namesList.count-1), 1);
|
||||
}
|
||||
}
|
||||
@@ -125,12 +114,12 @@ Item {
|
||||
|
||||
StatusBaseText {
|
||||
id: warningTextLabel
|
||||
visible: (namesModel.count === root.nameCountLimit)
|
||||
visible: (namesModel.count === 5)
|
||||
Layout.preferredWidth: 120
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
font.pixelSize: 10
|
||||
color: Theme.palette.dangerColor1
|
||||
text: root.nameCountLimit + " " + root.warningText
|
||||
text: root.warningText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,38 @@ Item {
|
||||
property string tertiaryDetail: ""
|
||||
property string resendText: ""
|
||||
property bool showResendButton: false
|
||||
property bool isMutualContact: false
|
||||
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
property StatusIconSettings icon1: StatusIconSettings {
|
||||
width: dummyImage.width
|
||||
height: dummyImage.height
|
||||
rotation: 0
|
||||
color: Theme.palette.indirectColor1
|
||||
background: StatusIconBackgroundSettings {
|
||||
width: 10
|
||||
height: 10
|
||||
color: Theme.palette.primaryColor1
|
||||
}
|
||||
// only used to get implicit width and height from the actual image
|
||||
property Image dummyImage: Image {
|
||||
source: icon1.name ? "../../../../assets/img/icons/" + icon1.name + ".svg": ""
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
property StatusIconSettings icon2: StatusIconSettings {
|
||||
width: dummyImage.width
|
||||
height: dummyImage.height
|
||||
rotation: 0
|
||||
color: Theme.palette.primaryColor1
|
||||
background: StatusIconBackgroundSettings {
|
||||
width: 10
|
||||
height: 10
|
||||
color: Theme.palette.indirectColor1
|
||||
}
|
||||
// only used to get implicit width and height from the actual image
|
||||
property Image dummyImage: Image {
|
||||
source: icon2.name ? "../../../../assets/img/icons/" + icon2.name + ".svg": ""
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
|
||||
signal clicked()
|
||||
signal resendClicked()
|
||||
@@ -53,10 +83,28 @@ Item {
|
||||
}
|
||||
}
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
}
|
||||
StatusContactVerificationIcons {
|
||||
isMutualContact: statusMessageHeader.isMutualContact
|
||||
trustIndicator: statusMessageHeader.trustIndicator
|
||||
}
|
||||
StatusRoundIcon {
|
||||
icon.background.width: icon1.background.width
|
||||
icon.background.height: icon1.background.height
|
||||
icon.background.color: icon1.background.color
|
||||
icon.width: icon1.width
|
||||
icon.height: icon1.height
|
||||
icon.name: icon1.name
|
||||
icon.rotation: icon1.rotation
|
||||
icon.color: icon1.color
|
||||
visible: !!icon.name
|
||||
}
|
||||
StatusRoundIcon {
|
||||
icon.background.width: icon2.background.width
|
||||
icon.background.height: icon2.background.height
|
||||
icon.background.color: icon2.background.color
|
||||
icon.width: icon2.width
|
||||
icon.height: icon2.height
|
||||
icon.name: icon2.name
|
||||
icon.rotation: icon2.rotation
|
||||
icon.color: icon2.color
|
||||
visible: !!icon.name
|
||||
}
|
||||
StatusBaseText {
|
||||
id: secondaryDisplayName
|
||||
|
||||
@@ -10,7 +10,6 @@ StatusChatListCategoryItem 0.1 StatusChatListCategoryItem.qml
|
||||
StatusChatListAndCategories 0.1 StatusChatListAndCategories.qml
|
||||
StatusChatToolBar 0.1 StatusChatToolBar.qml
|
||||
StatusContactRequestsIndicatorListItem 0.1 StatusContactRequestsIndicatorListItem.qml
|
||||
StatusContactVerificationIcons 0.1 StatusContactVerificationIcons.qml
|
||||
StatusDescriptionListItem 0.1 StatusDescriptionListItem.qml
|
||||
StatusLetterIdenticon 0.1 StatusLetterIdenticon.qml
|
||||
StatusListItem 0.1 StatusListItem.qml
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
/*!
|
||||
\qmltype StatusIdenticonRing
|
||||
\inherits Item
|
||||
\inqmlmodule StatusQ.Controls
|
||||
\since StatusQ.Controls 0.1
|
||||
\brief It provides lines wrapped into a ring around another component like avatars.
|
||||
|
||||
The \c StatusIdenticonRing item displays lines wrapped into a ring. The line is rendered clockwise.
|
||||
|
||||
N segments and M distinctive colors compose identicon lines.
|
||||
|
||||
Example of how the component looks like:
|
||||
\image status_identicon_ring.png
|
||||
|
||||
Example of how to use it:
|
||||
|
||||
\qml
|
||||
StatusIdenticonRing {
|
||||
anchors.fill: parent
|
||||
settings: StatusIdenticonRingSettings {
|
||||
totalRingUnits: 25
|
||||
initalAngleRad: 0
|
||||
ringPxSize: 1.5
|
||||
ringSpecModel: [ ListElement {colorId: 0; segmentLength: 1},
|
||||
ListElement {colorId: 28; segmentLength: 1},
|
||||
ListElement {colorId: 31; segmentLength: 1},
|
||||
ListElement {colorId: 22; segmentLength: 4},
|
||||
ListElement {colorId: 28; segmentLength: 3},
|
||||
ListElement {colorId: 27; segmentLength: 5},
|
||||
ListElement {colorId: 7; segmentLength: 5},
|
||||
ListElement {colorId: 13; segmentLength: 1},
|
||||
ListElement {colorId: 25; segmentLength: 4}]
|
||||
distinctiveColors: ["#000000", "#726F6F", "#C4C4C4",
|
||||
"#E7E7E7", "#FFFFFF", "#00FF00",
|
||||
"#009800", "#B8FFBB", "#FFC413",
|
||||
"#9F5947", "#FFFF00", "#A8AC00",
|
||||
"#FFFFB0", "#FF5733", "#FF0000",
|
||||
"#9A0000", "#FF9D9D", "#FF0099",
|
||||
"#C80078", "#FF00FF", "#900090",
|
||||
"#FFB0FF", "#9E00FF", "#0000FF",
|
||||
"#000086", "#9B81FF", "#3FAEF9",
|
||||
"#9A6600", "#00FFFF", "#008694",
|
||||
"#C2FFFF", "#00F0B6"]
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
Item {
|
||||
id: identiconRing
|
||||
|
||||
/*!
|
||||
\qmlproperty StatusIdenticonRingSettings StatusIdenticonRing::settings
|
||||
This property holds a set of settings for building the ring.
|
||||
*/
|
||||
property StatusIdenticonRingSettings settings: StatusIdenticonRingSettings {
|
||||
totalRingUnits: 1
|
||||
initalAngleRad: 0
|
||||
ringPxSize: 1.5
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real StatusIdenticonRing::segmentRadLen
|
||||
This property holds the total ring line length in radians. It depends on totalRingUnits value of settings object.
|
||||
*/
|
||||
readonly property real segmentRadLen: 2 * Math.PI / settings.totalRingUnits
|
||||
|
||||
visible: settings.ringSpecModel !== undefined
|
||||
|
||||
Canvas {
|
||||
function printArcSegment(context, xPos, yPos, radius, color, startAngle, arcAngleLen, lineWidth) {
|
||||
context.beginPath()
|
||||
context.arc(xPos, yPos, radius, startAngle, startAngle + arcAngleLen, false/*anticlockwise*/)
|
||||
context.strokeStyle = color
|
||||
context.lineWidth = lineWidth
|
||||
context.stroke()
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
onPaint: {
|
||||
const context = getContext("2d")
|
||||
const radius = (height - settings.ringPxSize) / 2
|
||||
const xPos = width / 2
|
||||
const yPos = height / 2
|
||||
let arcPos = settings.initalAngleRad
|
||||
context.reset()
|
||||
if(settings.ringSpecModel) {
|
||||
for (let i=0; i<settings.ringSpecModel.count; i++) {
|
||||
const segment = settings.ringSpecModel.get(i)
|
||||
printArcSegment(context,
|
||||
xPos,
|
||||
yPos,
|
||||
radius,
|
||||
settings.distinctiveColors[segment.colorId],
|
||||
arcPos,
|
||||
segment.segmentLength * identiconRing.segmentRadLen,
|
||||
settings.ringPxSize)
|
||||
arcPos += segment.segmentLength * identiconRing.segmentRadLen
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
import QtQuick 2.0
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls.Validators 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusPinInput
|
||||
\inherits Item
|
||||
\inqmlmodule StatusQ.Controls
|
||||
\since StatusQ.Controls 0.1
|
||||
\brief It allows entering an N pin length.
|
||||
|
||||
The \c StatusPinInput displays N visual circles corresponging with the pin length to introduce.
|
||||
|
||||
It runs a blinking animation when the control is focused and ready to introduce the pin, as well as, an hovering feedback when user is in the MouseArea where is able to click into the control.
|
||||
|
||||
This pin input control allows introducing validators.
|
||||
|
||||
Example of how the control looks like:
|
||||
\image status_pin_input.png
|
||||
|
||||
Example of how to use it:
|
||||
|
||||
\qml
|
||||
StatusPinInput {
|
||||
id: regexPinInput
|
||||
validator: StatusRegularExpressionValidator { regularExpression: /[0-9A-Za-z@]+/ }
|
||||
circleDiameter: 22
|
||||
circleSpacing: 22
|
||||
pinLen: 7
|
||||
}
|
||||
\endqml
|
||||
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
Item {
|
||||
id: root
|
||||
|
||||
/*!
|
||||
\qmlproperty string StatusPinInput::pinInput
|
||||
This property holds the introduced user pin.
|
||||
*/
|
||||
property alias pinInput: inputText.text
|
||||
|
||||
/*!
|
||||
\qmlproperty Validator StatusPinInput::validator
|
||||
This property allows you to set a validator on the StatusPinInput. When a validator is set the StatusPinInput will only accept
|
||||
input which leaves the pinInput property in an acceptable state.
|
||||
|
||||
Currently supported validators are qml StatusIntValidator and StatusRegularExpressionValidator.
|
||||
|
||||
An example of using validators is shown below, which allows input of integers between 0 and 999999 into the pin input
|
||||
|
||||
\qml
|
||||
StatusPinInput {
|
||||
id: numbersPinInput
|
||||
validator: StatusIntValidator{bottom: 0; top: 999999;}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
property alias validator: d.statusValidator
|
||||
|
||||
/*!
|
||||
\qmlproperty int StatusPinInput::pinLen
|
||||
This property allows you to set a specific pin input length. The default value is 6.
|
||||
*/
|
||||
property int pinLen: 6
|
||||
|
||||
/*!
|
||||
\qmlproperty int StatusPinInput::circleSpacing
|
||||
This property allows you to customize spacing between pin circles. The default value is 16 pixels.
|
||||
*/
|
||||
property int circleSpacing: 16
|
||||
|
||||
/*!
|
||||
\qmlproperty int StatusPinInput::circleDiameter
|
||||
This property allows you to customize pin circle diameter. The default value is 16 pixels.
|
||||
*/
|
||||
property int circleDiameter: 16
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property int currentPinIndex: 0
|
||||
|
||||
property StatusValidator statusValidator
|
||||
|
||||
function activateBlink () {
|
||||
const currItem = repeater.itemAt(d.currentPinIndex)
|
||||
if(currItem) {
|
||||
if((currItem.innerState === "NEXT") && (!currItem.blinkingAnimation.running)) {
|
||||
currItem.blinkingAnimation.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function deactivateBlink () {
|
||||
const currItem = repeater.itemAt(d.currentPinIndex)
|
||||
if(currItem) {
|
||||
if((currItem.innerState === "NEXT") && (currItem.blinkingAnimation.running)) {
|
||||
currItem.blinkingAnimation.stop()
|
||||
|
||||
// To ensure that the opacity does not remain in an intermediate state when forcing the animation to stop
|
||||
currItem.innerOpacity = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
\qmlmethod StatusPinInput::statesInitialization()
|
||||
|
||||
Initializes pin input bringing it to its initial state.
|
||||
|
||||
It is directly called in Component.onCompleted slot and can be called whenever you need resetting it.
|
||||
*/
|
||||
function statesInitialization() {
|
||||
d.currentPinIndex = 0
|
||||
repeater.itemAt(d.currentPinIndex).innerState = "NEXT"
|
||||
for (var i = 1; i < root.pinLen; i++) {
|
||||
repeater.itemAt(i).innerState = "EMPTY"
|
||||
}
|
||||
}
|
||||
|
||||
width: (root.circleDiameter + root.circleSpacing) * root.pinLen
|
||||
height: root.circleDiameter
|
||||
|
||||
Component.onCompleted: { statesInitialization() }
|
||||
|
||||
// Pin input data management object:
|
||||
TextInput {
|
||||
id: inputText
|
||||
visible: false
|
||||
focus: true
|
||||
maximumLength: root.pinLen
|
||||
validator: d.statusValidator.validatorObj
|
||||
onTextChanged: {
|
||||
// Modify state of current introduced character position:
|
||||
if(text.length >= (d.currentPinIndex + 1)) {
|
||||
repeater.itemAt(d.currentPinIndex).innerState = "FILLED"
|
||||
|
||||
// Update next:
|
||||
d.currentPinIndex++
|
||||
if(d.currentPinIndex < root.pinLen)
|
||||
repeater.itemAt(d.currentPinIndex).innerState = "NEXT"
|
||||
|
||||
}
|
||||
// Modify state of current removed character position:
|
||||
else if (text.length <= (d.currentPinIndex + 1)) {
|
||||
if(d.currentPinIndex < root.pinLen)
|
||||
repeater.itemAt(d.currentPinIndex).innerState = "EMPTY"
|
||||
d.currentPinIndex--
|
||||
repeater.itemAt(d.currentPinIndex).innerState = "NEXT"
|
||||
}
|
||||
|
||||
// Some component validations:
|
||||
if(text.length !== d.currentPinIndex)
|
||||
console.error("StatusPinInput input management error. Current pin length must be "+ text.length + "and is " + d.currentPinIndex)
|
||||
}
|
||||
onFocusChanged: { if(!focus) { d.deactivateBlink () } }
|
||||
}
|
||||
|
||||
// Pin input visual objects:
|
||||
Row {
|
||||
spacing: root.circleSpacing
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: root.pinLen
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
property string innerState: "EMPTY"
|
||||
property alias blinkingAnimation: blinkingAnimation
|
||||
property alias innerOpacity: inner.opacity
|
||||
|
||||
width: root.circleDiameter
|
||||
height: width
|
||||
color: Theme.palette.primaryColor2
|
||||
radius: 0.5 * width
|
||||
|
||||
Rectangle {
|
||||
id: inner
|
||||
state: background.innerState
|
||||
anchors.centerIn: parent
|
||||
height: width
|
||||
color: Theme.palette.primaryColor1
|
||||
radius: 0.5 * width
|
||||
states: [
|
||||
State {
|
||||
name: "NEXT"
|
||||
StateChangeScript { script: { if(inputText.focus) blinkingAnimation.start() } }
|
||||
PropertyChanges {target: inner; width: root.circleDiameter / 2}
|
||||
},
|
||||
State {
|
||||
name: "FILLED"
|
||||
StateChangeScript { script: if(blinkingAnimation.running) blinkingAnimation.stop() }
|
||||
PropertyChanges {target: inner; width: root.circleDiameter}
|
||||
PropertyChanges {target: inner; opacity: 1}
|
||||
},
|
||||
State {
|
||||
name: "EMPTY"
|
||||
StateChangeScript { script: if(blinkingAnimation.running) blinkingAnimation.stop() }
|
||||
PropertyChanges {target: inner; width: 0}
|
||||
PropertyChanges {target: inner; opacity: 1}
|
||||
}
|
||||
]
|
||||
|
||||
// Animation on transitions
|
||||
Behavior on width { NumberAnimation { duration: 200 } }
|
||||
|
||||
// Animation on "cursor" blinking
|
||||
SequentialAnimation {
|
||||
id: blinkingAnimation
|
||||
loops: Animation.Infinite
|
||||
NumberAnimation { target: inner; property: "opacity"; to: 0; duration: 800 }
|
||||
NumberAnimation { target: inner; property: "opacity"; to: 1; duration: 800 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
|
||||
// MouseArea behavior:
|
||||
onClicked: {
|
||||
inputText.forceActiveFocus()
|
||||
d.activateBlink ()
|
||||
}
|
||||
onContainsMouseChanged: { if(containsMouse) { cursorShape = Qt.PointingHandCursor } }
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusIntValidator
|
||||
\inherits StatusValidator
|
||||
\inqmlmodule StatusQ.Controls.Validators
|
||||
\since StatusQ.Controls.Validators 0.1
|
||||
\brief The StatusIntValidator type provides a validator for integer values.
|
||||
|
||||
The \c StatusIntValidator type provides a validator for integer values.
|
||||
|
||||
It is a wrapper of QML type \l{https://doc.qt.io/qt-5/qml-qtquick-intvalidator.html}{IntValidator}.
|
||||
|
||||
Example of how to use it:
|
||||
|
||||
\qml
|
||||
StatusIntValidator {
|
||||
bottom: 0
|
||||
top: 125
|
||||
errorMessage: qsTr("This is an invalid numeric value")
|
||||
}
|
||||
\endqml
|
||||
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
StatusValidator {
|
||||
id: root
|
||||
|
||||
/*!
|
||||
\qmlproperty string StatusIntValidator::bottom
|
||||
This property holds the validator's lowest acceptable value. By default, this property's value is derived from the lowest signed integer available (typically -2147483647).
|
||||
*/
|
||||
property int bottom
|
||||
|
||||
/*!
|
||||
\qmlproperty string StatusIntValidator::locale
|
||||
This property holds the name of the locale used to interpret the number.
|
||||
*/
|
||||
property string locale
|
||||
|
||||
/*!
|
||||
\qmlproperty string StatusIntValidator::top
|
||||
This property holds the validator's highest acceptable value. By default, this property's value is derived from the highest signed integer available (typically 2147483647).
|
||||
*/
|
||||
property int top
|
||||
|
||||
name: "intValidator"
|
||||
errorMessage: "Please enter a valid numeric value."
|
||||
validatorObj: IntValidator { bottom: root.bottom; locale: root.locale; top: root.top }
|
||||
|
||||
validate: function (t) {
|
||||
// Basic validation management
|
||||
return root.validatorObj.validate() === IntValidator.Acceptable
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusRegularExpressionValidator
|
||||
\inherits StatusValidator
|
||||
\inqmlmodule StatusQ.Controls.Validators
|
||||
\since StatusQ.Controls.Validators 0.1
|
||||
\brief The StatusRegularExpressionValidator type provides a validator for regular expressions.
|
||||
|
||||
The \c StatusRegularExpressionValidator type provides a validator, that counts as valid any string which matches a specified regular expression.
|
||||
|
||||
It is a wrapper of QML type \l{https://doc.qt.io/qt-5/qml-qtquick-regularexpressionvalidator.html}{RegularExpressionValidator}.
|
||||
|
||||
Example of how to use it:
|
||||
|
||||
\qml
|
||||
StatusRegularExpressionValidator {
|
||||
regularExpression: /[0-9A-Za-z@]+/
|
||||
errorMessage: qsTr("Please enter a valid regular expression.")
|
||||
}
|
||||
\endqml
|
||||
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
StatusValidator {
|
||||
id: root
|
||||
|
||||
/*!
|
||||
\qmlproperty string StatusRegularExpressionValidator::regularExpression
|
||||
This property holds the regular expression used for validation.
|
||||
|
||||
Note that this property should be a regular expression in JS syntax, e.g /a/ for the regular expression matching "a".
|
||||
|
||||
By default, this property contains a regular expression with the pattern .* that matches any string.
|
||||
|
||||
Some more examples of regular expressions:
|
||||
|
||||
> A list of numbers with one to three positions separated by a comma:
|
||||
\qml
|
||||
/\d{1,3}(?:,\d{1,3})+$/
|
||||
\endqml
|
||||
|
||||
> An amount consisting of up to 3 numbers before the decimal point, and 1 to 2 after the decimal point:
|
||||
\qml
|
||||
/(\d{1,3})([.,]\d{1,2})?$/
|
||||
\endqml
|
||||
*/
|
||||
property var regularExpression
|
||||
|
||||
name: "regex"
|
||||
errorMessage: "Please enter a valid regular expression."
|
||||
validatorObj: RegularExpressionValidator { regularExpression: root.regularExpression }
|
||||
|
||||
validate: function (t) {
|
||||
// Basic validation management
|
||||
return root.validatorObj.validate() === RegularExpressionValidator.Acceptable
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ QtObject {
|
||||
|
||||
property string name: ""
|
||||
property string errorMessage: "invalid input"
|
||||
property var validatorObj
|
||||
|
||||
property var validate: function (value) {
|
||||
return true
|
||||
|
||||
@@ -4,9 +4,7 @@ StatusAddressValidator 0.1 StatusAddressValidator.qml
|
||||
StatusAddressOrEnsValidator 0.1 StatusAddressOrEnsValidator.qml
|
||||
StatusAsyncValidator 0.1 StatusAsyncValidator.qml
|
||||
StatusAsyncEnsValidator 0.1 StatusAsyncEnsValidator.qml
|
||||
StatusIntValidator 0.1 StatusIntValidator.qml
|
||||
StatusMinLengthValidator 0.1 StatusMinLengthValidator.qml
|
||||
StatusMaxLengthValidator 0.1 StatusMaxLengthValidator.qml
|
||||
StatusRegularExpressionValidator 0.1 StatusRegularExpressionValidator.qml
|
||||
StatusUrlValidator 0.1 StatusUrlValidator.qml
|
||||
StatusValidator 0.1 StatusValidator.qml
|
||||
|
||||
@@ -8,7 +8,6 @@ StatusChatInfoButton 0.1 StatusChatInfoButton.qml
|
||||
StatusChatListCategoryItemButton 0.1 StatusChatListCategoryItemButton.qml
|
||||
StatusColorSelector 0.1 StatusColorSelector.qml
|
||||
StatusIconTabButton 0.1 StatusIconTabButton.qml
|
||||
StatusIdenticonRing 0.1 StatusIdenticonRing.qml
|
||||
StatusNavBarTabButton 0.1 StatusNavBarTabButton.qml
|
||||
StatusTabBarIconButton 0.1 StatusTabBarIconButton.qml
|
||||
StatusToolTip 0.1 StatusToolTip.qml
|
||||
@@ -25,7 +24,6 @@ StatusSelect 0.1 StatusSelect.qml
|
||||
StatusBaseInput 0.1 StatusBaseInput.qml
|
||||
StatusInput 0.1 StatusInput.qml
|
||||
StatusPickerButton 0.1 StatusPickerButton.qml
|
||||
StatusPinInput 0.1 StatusPinInput.qml
|
||||
StatusProgressBar 0.1 StatusProgressBar.qml
|
||||
StatusPasswordStrengthIndicator 0.1 StatusPasswordStrengthIndicator.qml
|
||||
StatusSwitchTabButton 0.1 StatusSwitchTabButton.qml
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
import QtQuick 2.13
|
||||
import StatusQ.Core 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusIdenticonRingSettings
|
||||
\inherits QtObject
|
||||
\inqmlmodule StatusQ.Core
|
||||
\since StatusQ.Core 0.1
|
||||
\brief It describes identicon ring settings.
|
||||
|
||||
The \c StatusIdenticonRingSettings object is not a graphical component just an object to encapsulate identicon ring settings.
|
||||
|
||||
Example of how to use it:
|
||||
|
||||
\qml
|
||||
StatusIdenticonRingSettings {
|
||||
totalRingUnits: 25
|
||||
initalAngleRad: 0
|
||||
ringPxSize: 1.5
|
||||
ringSpecModel: [ ListElement {colorId: 0; segmentLength: 1},
|
||||
ListElement {colorId: 28; segmentLength: 1},
|
||||
ListElement {colorId: 31; segmentLength: 1},
|
||||
ListElement {colorId: 22; segmentLength: 4},
|
||||
ListElement {colorId: 28; segmentLength: 3},
|
||||
ListElement {colorId: 27; segmentLength: 5},
|
||||
ListElement {colorId: 7; segmentLength: 5},
|
||||
ListElement {colorId: 13; segmentLength: 1},
|
||||
ListElement {colorId: 25; segmentLength: 4}]
|
||||
distinctiveColors: ["#000000", "#726F6F", "#C4C4C4",
|
||||
"#E7E7E7", "#FFFFFF", "#00FF00",
|
||||
"#009800", "#B8FFBB", "#FFC413",
|
||||
"#9F5947", "#FFFF00", "#A8AC00",
|
||||
"#FFFFB0", "#FF5733", "#FF0000",
|
||||
"#9A0000", "#FF9D9D", "#FF0099",
|
||||
"#C80078", "#FF00FF", "#900090",
|
||||
"#FFB0FF", "#9E00FF", "#0000FF",
|
||||
"#000086", "#9B81FF", "#3FAEF9",
|
||||
"#9A6600", "#00FFFF", "#008694",
|
||||
"#C2FFFF", "#00F0B6"]
|
||||
}
|
||||
\endqml
|
||||
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
QtObject {
|
||||
id: statusIdenticonRingSettings
|
||||
|
||||
/*!
|
||||
\qmlproperty ListModel StatusIdenticonRingSettings::ringSpecModel
|
||||
This is a REQUIRED property that contains a ListModel object that describes each ring segment color and length.
|
||||
Example of use: [ListElement {colorId: 0; segmentLength: 1}, ...]
|
||||
*/
|
||||
property ListModel ringSpecModel
|
||||
|
||||
/*!
|
||||
\qmlproperty var StatusIdenticonRingSettings::distinctiveColors
|
||||
This is a REQUIRED property that holds an string array of disctinctive segment colors.
|
||||
*/
|
||||
property var distinctiveColors
|
||||
|
||||
/*!
|
||||
\qmlproperty real StatusIdenticonRingSettings::totalRingUnits
|
||||
This property provides the total number of units the identicon ring is composed by.
|
||||
*/
|
||||
property real totalRingUnits
|
||||
|
||||
/*!
|
||||
\qmlproperty real StatusIdenticonRingSettings::initalAngleRad
|
||||
This property provides the initial angle, in radians, the identicon ring will start rendering the line.
|
||||
*/
|
||||
property real initalAngleRad
|
||||
|
||||
/*!
|
||||
\qmlproperty real StatusIdenticonRingSettings::ringPxSize
|
||||
This property provides the pixels size of the ring line.
|
||||
*/
|
||||
property real ringPxSize
|
||||
}
|
||||
@@ -158,13 +158,6 @@ ThemePalette {
|
||||
getColor('brown3')
|
||||
]
|
||||
|
||||
identiconRingColors: ["#000000", "#726F6F", "#C4C4C4", "#E7E7E7", "#FFFFFF", "#00FF00",
|
||||
"#009800", "#B8FFBB", "#FFC413", "#9F5947", "#FFFF00", "#A8AC00",
|
||||
"#FFFFB0", "#FF5733", "#FF0000", "#9A0000", "#FF9D9D", "#FF0099",
|
||||
"#C80078", "#FF00FF", "#900090", "#FFB0FF", "#9E00FF", "#0000FF",
|
||||
"#000086", "#9B81FF", "#3FAEF9", "#9A6600", "#00FFFF", "#008694",
|
||||
"#C2FFFF", "#00F0B6"]
|
||||
|
||||
property QtObject statusAppLayout: QtObject {
|
||||
property color backgroundColor: baseColor3
|
||||
property color rightPanelBackgroundColor: baseColor3
|
||||
|
||||
@@ -156,13 +156,6 @@ ThemePalette {
|
||||
getColor('brown')
|
||||
]
|
||||
|
||||
identiconRingColors: ["#000000", "#726F6F", "#C4C4C4", "#E7E7E7", "#FFFFFF", "#00FF00",
|
||||
"#009800", "#B8FFBB", "#FFC413", "#9F5947", "#FFFF00", "#A8AC00",
|
||||
"#FFFFB0", "#FF5733", "#FF0000", "#9A0000", "#FF9D9D", "#FF0099",
|
||||
"#C80078", "#FF00FF", "#900090", "#FFB0FF", "#9E00FF", "#0000FF",
|
||||
"#000086", "#9B81FF", "#3FAEF9", "#9A6600", "#00FFFF", "#008694",
|
||||
"#C2FFFF", "#00F0B6"]
|
||||
|
||||
property QtObject statusAppLayout: QtObject {
|
||||
property color backgroundColor: white
|
||||
property color rightPanelBackgroundColor: white
|
||||
|
||||
@@ -92,8 +92,6 @@ QtObject {
|
||||
|
||||
property var accountColors: []
|
||||
|
||||
property var identiconRingColors: []
|
||||
|
||||
property QtObject statusAppLayout: QtObject {
|
||||
property color backgroundColor
|
||||
property color rightPanelBackgroundColor
|
||||
|
||||
@@ -4,7 +4,6 @@ StatusBaseText 0.1 StatusBaseText.qml
|
||||
StatusIcon 0.1 StatusIcon.qml
|
||||
StatusIconSettings 0.1 StatusIconSettings.qml
|
||||
StatusIconBackgroundSettings 0.1 StatusIconBackgroundSettings.qml
|
||||
StatusIdenticonRingSettings 0.1 StatusIdenticonRingSettings.qml
|
||||
StatusImageSettings 0.1 StatusImageSettings.qml
|
||||
StatusModalHeaderSettings 0.1 StatusModalHeaderSettings.qml
|
||||
StatusTooltipSettings 0.1 StatusTooltipSettings.qml
|
||||
|
||||
@@ -21,6 +21,8 @@ Menu {
|
||||
property var closeHandler
|
||||
|
||||
dim: true
|
||||
Overlay.modeless: MouseArea {}
|
||||
|
||||
|
||||
signal menuItemClicked(int menuIndex)
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ StatusPopupMenu {
|
||||
|
||||
property var searchPopup
|
||||
property var locationModel
|
||||
readonly property int numDefaultItems: 2
|
||||
|
||||
signal itemClicked(string firstLevelItemValue, string secondLevelItemValue)
|
||||
|
||||
@@ -44,7 +43,7 @@ StatusPopupMenu {
|
||||
color: model.iconColor,
|
||||
isLetterIdenticon: !model.imageSource && !model.iconName
|
||||
});
|
||||
root.insertMenu(index + numDefaultItems, item);
|
||||
root.insertMenu(index+2, item);
|
||||
} else {
|
||||
item.value = model.value
|
||||
item.text = model.title;
|
||||
@@ -53,7 +52,7 @@ StatusPopupMenu {
|
||||
item.iconSettings.isLetterIdenticon = !model.imageSource && !model.iconName
|
||||
item.image.source = model.imageSource;
|
||||
item.image.isIdenticon = model.isIdenticon;
|
||||
root.insertItem(index + numDefaultItems, item);
|
||||
root.insertItem(index+2, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,6 @@ StatusModal {
|
||||
property Menu searchOptionsPopupMenu: Menu { }
|
||||
property var searchResults: [ ]
|
||||
property var searchSelectionButton
|
||||
// This function is called to know if the popup accepts clicks in the title
|
||||
// If it does not, the clicks on the titles mousearea will be propagated to the main body instead
|
||||
property var acceptsTitleClick: function(titleId) {return true}
|
||||
|
||||
signal resultItemClicked(string itemId)
|
||||
signal resultItemTitleClicked(string titleId)
|
||||
@@ -278,11 +275,8 @@ StatusModal {
|
||||
root.resultItemClicked(itemId)
|
||||
}
|
||||
|
||||
propagateTitleClicks: !root.acceptsTitleClick(titleId)
|
||||
onTitleClicked: {
|
||||
if (root.acceptsTitleClick(titleId)) {
|
||||
root.resultItemTitleClicked(titleId)
|
||||
}
|
||||
root.resultItemTitleClicked(titleId)
|
||||
}
|
||||
}
|
||||
section.property: "sectionName"
|
||||
|
||||
@@ -323,11 +323,5 @@
|
||||
<file>src/StatusQ/Components/StatusTagSelector.qml</file>
|
||||
<file>src/StatusQ/Components/StatusToastMessage.qml</file>
|
||||
<file>src/StatusQ/Components/StatusWizardStepper.qml</file>
|
||||
<file>src/StatusQ/Components/StatusContactVerificationIcons.qml</file>
|
||||
<file>src/StatusQ/Controls/StatusIdenticonRing.qml</file>
|
||||
<file>src/StatusQ/Core/StatusIdenticonRingSettings.qml</file>
|
||||
<file>src/StatusQ/Controls/StatusPinInput.qml</file>
|
||||
<file>src/StatusQ/Controls/Validators/StatusRegularExpressionValidator.qml</file>
|
||||
<file>src/StatusQ/Controls/Validators/StatusIntValidator.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
Reference in New Issue
Block a user