Compare commits

..
Author SHA1 Message Date
Alexandra Betouni f4983e22fd feat(StatusQ.Components): Adding StatusToastMessage
Added StatusToastMessage component, an example page
as well as a demonstration in chat view

Closes #521
2022-02-07 18:53:21 +02:00
10180 changed files with 598 additions and 24387 deletions
-17
View File
@@ -1,17 +0,0 @@
### Checklist
- [ ] follow [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)
- the scope should be the component's name e.g: `feat(StatusListItem): ... `
- when adding new components, the scope is the module e.g: `feat(StatusQ.Controls): ...`
- [ ] add documentation if necessary (new component, new feature)
- [ ] update sandbox app
- in case of new component, add new component page
- in case of new features, add variation to existing component page
- nice to have: add it to the demo application as well
- [ ] test changes in both light and dark theme?
- [ ] is this a breaking change?
- [ ] use the dedicated `BREAKING CHANGE` commit message section
- [ ] resolve breaking changes in [status-desktop](https://github.com/status-im/status-desktop)
- [ ] (pre-merge) adapt code to breaking changes
- [ ] (post-merge) update StatusQ submodule pointer
- [ ] test changes in [status-desktop](https://github.com/status-im/status-desktop)
-4
View File
@@ -13,7 +13,3 @@ Makefile
*_qml.cpp
*_qmlcache.qrc
sandbox/qmlcache_loader.cpp
doc/html
CMakeLists.txt.user
.vscode
build/
-57
View File
@@ -1,60 +1,3 @@
<a name=""></a>
## 0.25.0 (2022-03-07)
#### Bug Fixes
* **@StatusListItem:** fix left padding ([f574e390](f574e390))
* **StatusListItem:** add propagateTitleClicks property to StatusListItem ([8495fae8](8495fae8))
* **StatusQ.Popups:** removed overlay setting (#557) ([665141f8](665141f8))
* **StatusTagSelector:** Updates and fixes in the component ([07a5dc09](07a5dc09))
* **build:** fix linux build ([9d06aae1](9d06aae1), closes [#413](413))
* **sandbox:** Fix results popup component position ([cdf51fef](cdf51fef))
#### Features
* **@StatusListItem:** add option for tags ([381150a7](381150a7))
* **StatusChatList:** Highlight chat item at creation time ([9e6fbe95](9e6fbe95))
* **StatusChatListItem:** enable assigning emoji to chat item ([5fac8774](5fac8774))
* **StatusContactVerificationIcons:** Create new row control that includes mutual connect and trust indicator icons (#559) ([c0f825c6](c0f825c6), closes [#542](542))
* **StatusQ:** Moving docs outside sandbox ([825999b1](825999b1))
* **StatusQ.Core:** add new arrow-left icon ([e9f20be1](e9f20be1))
* **StatusSmartIdenticon:** Add support for color rings in StatusSmartIdenticon (#553) ([3b86d13a](3b86d13a), closes [#517](517))
#### Breaking Changes
* **StatusContactVerificationIcons:** Create new row control that includes mutual connect and trust indicator icons (#559) ([c0f825c6](c0f825c6), closes [#542](542))
<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)
#### Bug Fixes
* Icon components had wrong color in sandbox app ([b632c712](b632c712), closes [#538](538))
* **StatusChatList:** unexisting property name for chat item fixed ([c2e07517](c2e07517))
#### Features
* **StatusQ.Components:**
* Adding StatusToastMessage ([7b290ddd](7b290ddd), closes [#521](521))
* Adding StatusTagSelector component ([094dee49](094dee49), closes [#526](526))
<a name=""></a>
## Version 0.22.0 (2022-01-31)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

-19
View File
@@ -1,19 +0,0 @@
/*!
\page statusq-index.html
\title StatusQ
\brief A components library for Status desktop client.
StatusQ provides a collection of components....
StatusQ - Components and Interfaces
\list
\li \l{StatusQ Components}{Components}
\li \l{StatusQ Controls}{Controls}
\li \l{StatusQ Core}{Core}
\li \l{StatusQ Layout}{Layout}
\li \l{StatusQ Platform}{Platform}
\li \l{StatusQ Popups}{Popups}
\endlist
*/
-41
View File
@@ -1,41 +0,0 @@
/*!
\qmlmodule StatusQ.Components 0.1
\title StatusQ Components
\brief Basic set of Components StatusQ components
This is a listing of all Components components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusAddress}
\li \l{StatusBadge}
\li \l{StatusChatInfoToolBar}
\li \l{StatusChatList}
\li \l{StatusChatListItem}
\li \l{StatusImageSettings}
\li \l{StatusChatListCategory}
\li \l{StatusChatListCategoryItem}
\li \l{StatusChatListAndCategories}
\li \l{StatusChatToolBar}
\li \l{StatusContactRequestsIndicatorListItem}
\li \l{StatusDescriptionListItem}
\li \l{StatusLetterIdenticon}
\li \l{StatusListItem}
\li \l{StatusListSectionHeadline}
\li \l{StatusLoadingIndicator}
\li \l{StatusMemberListItem}
\li \l{StatusNavigationListItem}
\li \l{StatusNavigationPanelHeadline}
\li \l{StatusRoundIcon}
\li \l{StatusRoundedImage}
\li \l{StatusMacWindowButtons}
\li \l{StatusListItemBadge}
\li \l{StatusExpandableItem}
\li \l{StatusSmartIdenticon}
\li \l{StatusMessage}
\li \l{StatusMessageDetails}
\li \l{StatusTagSelector}
\li \l{StatusToastMessage}
\endlist
*/
-47
View File
@@ -1,47 +0,0 @@
/*!
\qmlmodule StatusQ.Controls 0.1
\title StatusQ Controls
\brief Basic set of Controls StatusQ components
This is a listing of all Controls components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusAccountSelector}
\li \l{StatusAssetSelector}
\li \l{StatusBanner}
\li \l{StatusChatCommandButton}
\li \l{StatusChatInfoButton}
\li \l{StatusChatListCategoryItemButton}
\li \l{StatusColorSelector}
\li \l{StatusIconTabButton}
\li \l{StatusNavBarTabButton}
\li \l{StatusTabBarIconButton}
\li \l{StatusToolTip}
\li \l{StatusBaseButton}
\li \l{StatusButton}
\li \l{StatusFlatButton}
\li \l{StatusRoundButton}
\li \l{StatusFlatRoundButton}
\li \l{StatusSwitch}
\li \l{StatusRadioButton}
\li \l{StatusCheckBox}
\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}
\li \l{StatusSwitchTabBar}
\li \l{StatusSelectableText}
\li \l{StatusWalletColorButton}
\li \l{StatusWalletColorSelect}
\li \l{StatusRegularExpressionValidator}
\li \l{StatusIntValidator}
\endlist
*/
-23
View File
@@ -1,23 +0,0 @@
/*!
\qmlmodule StatusQ.Core 0.1
\title StatusQ Core
\brief Basic set of Core StatusQ components
This is a listing of all Core components. These
files are available for general import and they are based off the \l{https://doc.qt.io/qt-5/qtquick-qmlmodule.html}{Qt
Quick Primitives} and \l{https://doc.qt.io/archives/qt-5.11/qtquick-controls2-qmlmodule.html}{Qt Quick Controls 2}.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusAppNavBarFilterModel}
\li \l{StatusBaseText}
\li \l{StatusIcon}
\li \l{StatusIconBackgroundSettings}
\li \l{StatusIconSettings}
\li \l{StatusIdenticonRingSettings}
\li \l{StatusImageSettings}
\li \l{StatusModalHeaderSettings}
\li \l{StatusTooltipSettings}
\endlist
*/
-16
View File
@@ -1,16 +0,0 @@
/*!
\qmlmodule StatusQ.Layout 0.1
\title StatusQ Layout
\brief Basic set of Layout StatusQ components
This is a listing of all Layout components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusAppLayout}
\li \l{StatusAppNavBar}
\li \l{StatusAppTwoPanelLayout}
\li \l{StatusAppThreePanelLayout}
\endlist
*/
-15
View File
@@ -1,15 +0,0 @@
/*!
\qmlmodule StatusQ.Platform 0.1
\title StatusQ Platform
\brief Basic set of Platform StatusQ components
This is a listing of all Platform components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusMacTrafficLights}
\li \l{StatusMacNotification}
\li \l{StatusWindowsTitleBar}
\endlist
*/
-22
View File
@@ -1,22 +0,0 @@
/*!
\qmlmodule StatusQ.Popups 0.1
\title StatusQ Popups
\brief Basic set of Popups StatusQ components
This is a listing of all Popups components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusMenuSeparator}
\li \l{StatusPopupMenu}
\li \l{StatusMenuItem}
\li \l{StatusMenuItemDelegate}
\li \l{StatusModal}
\li \l{StatusSearchPopup}
\li \l{StatusModalDivider}
\li \l{StatusSearchPopupMenuItem}
\li \l{StatusSearchLocationMenu}
\li \l{StatusSpellcheckingMenuItems}
\endlist
*/
-36
View File
@@ -1,36 +0,0 @@
project = StatusQ
version = 0.1
description = StatusQ Project
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
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 \
sources.fileextensions = "*.cpp *.qdoc *.qml"
depends += qtcore \
qtquick \
qtqml \
qtgui \
qtdoc \
qtquickcontrols2
navigation.homepage = "StatusQ"
outputdir = $PWD/html
outputformats = HTML
HTML.stylesheets = style.css
HTML.headerstyles = "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\"/>\n"
HTML.postheader = "<p class=\"header\"><small>StatusQ - A Components selection for Status dekstop client. </p></small></p><hr/>"
HTML.footer = "<hr/><div class=\"footer\"><p><acronym title=\"Copyright\">&copy;</acronym> 2022 Status. All rights reserved. <a href=\"https://status.im\" target=\"_blank\"><small>status.im</a></small></p></div>"
-41
View File
@@ -1,41 +0,0 @@
body {
font-family: "Verdana";
font-size: 14px;
max-width: 80%;
margin: auto;
}
h1, h2, h3 {
color: #4360DF;
}
div.sidebar {
float: right;
}
pre {
padding: 15px;
}
div.qmlproto {
padding-left: 15px;
padding-right: 15px;
}
pre, div.qmlproto {
font-family: "Courier New";
font-size: 20px;
margin-left: 2em;
background-color: #F0F2F5;
}
hr {
margin-top: 2em;
margin-bottom: 2em;
}
p.header {
margin-bottom: -1em;
}
p.footer {
text-align: right;
margin-top: -1em;
}
+2 -57
View File
@@ -4,7 +4,6 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Utils 0.1
GridLayout {
columns: 1
@@ -65,12 +64,6 @@ GridLayout {
type: StatusChatListItem.Type.CommunityChat
}
StatusChatListItem {
name: "community-channel-emoji"
type: StatusChatListItem.Type.CommunityChat
icon.emoji: "😁"
}
StatusChatListItem {
name: "community-channel-with-image"
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
@@ -329,43 +322,6 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
badge.icon.isLetterIdenticon: true
}
StatusListItem {
title: "List Item with Tags"
icon.isLetterIdenticon: true
bottomModel: 3
bottomDelegate: StatusListItemTag {
title: "tag"
icon.isLetterIdenticon: true
}
}
StatusListItem {
title: "List Item with Inline Tags"
icon.isLetterIdenticon: true
tagsModel : 2
tagsDelegate: StatusListItemTag {
color: "blue"
height: 24
radius: 6
closeButtonVisible: false
icon.emoji: "😁"
icon.emojiSize: Emoji.size.verySmall
icon.isLetterIdenticon: true
title: "helloworld.eth"
titleText.font.pixelSize: 12
titleText.color: Theme.palette.indirectColor1
}
}
StatusListItem {
title: "List Item with Emoji"
subTitle: "Emoji"
icon.emoji: "😁"
icon.color: "yellow"
icon.letterSize: 14
icon.isLetterIdenticon: true
}
StatusDescriptionListItem {
title: "Title"
subTitle: "Subtitle"
@@ -395,29 +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
}
StatusMemberListItem {
nickName: "carmen.eth"
isOnline: false
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
trustIndicator: StatusMemberListItem.TrustedType.Untrustworthy
}
StatusMemberListItem {
-41
View File
@@ -78,11 +78,6 @@ Column {
onClicked: editTitleModal.open()
}
StatusButton {
text: "Modal with Advanced Header/Footer"
onClicked: advancedHeaderFooterModal.open()
}
StatusModal {
id: simpleModal
anchors.centerIn: parent
@@ -358,42 +353,6 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
header.editable: true
}
StatusModal {
id: advancedHeaderFooterModal
anchors.centerIn: parent
showHeader: false
showFooter: false
showAdvancedHeader: true
showAdvancedFooter: true
height: 200
advancedHeaderComponent: Rectangle {
width: parent.width
height: 50
color: Theme.palette.baseColor1
border.width: 1
StatusBaseText {
anchors.centerIn: parent
text: "Add any header here"
font.pixelSize: 15
color: Theme.palette.directColor1
}
}
advancedFooterComponent: Rectangle {
width: parent.width
height: 50
color: Theme.palette.baseColor1
border.width: 1
StatusBaseText {
anchors.centerIn: parent
text: "Add any footer here"
font.pixelSize: 15
color: Theme.palette.directColor1
}
}
}
ListModel {
id: dummyAccountsModel
ListElement{name: "Account 1"; iconName: "filled-account"}
+1 -2
View File
@@ -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
+171 -7
View File
@@ -1,6 +1,8 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQml.Models 2.2
import QtGraphicalEffects 1.0
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
@@ -26,19 +28,33 @@ Page {
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: 17
maxHeight: root.height
implicitHeight: 44
toLabelText: qsTr("To: ")
warningText: qsTr("USER LIMIT REACHED")
listLabel: qsTr("Contacts")
warningText: qsTr("5 USER LIMIT REACHED")
//simulate model filtering, TODO this
//makes more sense to be provided by the backend
//figure how real implementation should look like
property ListModel sortedList: ListModel { }
onTextChanged: {
sortModel(root.contactsModel);
sortedList.clear();
if (text !== "") {
for (var i = 0; i < contactsModel.count; i++ ) {
var entry = contactsModel.get(i);
if (entry.name.toLowerCase().includes(text.toLowerCase())) {
sortedList.insert(sortedList.count, {"publicId": entry.publicId, "name": entry.name,
"icon": entry.icon, "isIdenticon": entry.isIdenticon,
"onlineStatus": entry.onlineStatus});
userListView.model = sortedList;
}
}
} else {
userListView.model = contactsModel;
}
}
Component.onCompleted: { sortModel(root.contactsModel); }
}
StatusButton {
implicitHeight: 44
Layout.alignment: Qt.AlignTop
enabled: (tagSelector.namesModel.count > 0)
text: "Confirm"
}
@@ -46,7 +62,155 @@ Page {
contentItem: Item {
anchors.fill: parent
anchors.topMargin: 68
anchors.topMargin: headerRow.height + 16
Item {
anchors.fill: parent
visible: (contactsModel.count > 0)
StatusBaseText {
id: contactsLabel
font.pixelSize: 15
color: Theme.palette.baseColor1
text: "Contacts"
}
Control {
width: 360
anchors {
top: contactsLabel.bottom
topMargin: 8//Style.current.padding
bottom: parent.bottom
bottomMargin: 20//Style.current.bigPadding
}
background: Rectangle {
id: statusPopupMenuBackgroundContent
anchors.left: parent.left
anchors.right: parent.right
height: (userListView.height + 8)
visible: (tagSelector.sortedList.count > 0)
color: Theme.palette.statusPopupMenu.backgroundColor
radius: 8
layer.enabled: true
layer.effect: DropShadow {
width: statusPopupMenuBackgroundContent.width
height: statusPopupMenuBackgroundContent.height
x: statusPopupMenuBackgroundContent.x
visible: statusPopupMenuBackgroundContent.visible
source: statusPopupMenuBackgroundContent
horizontalOffset: 0
verticalOffset: 4
radius: 12
samples: 25
spread: 0.2
color: Theme.palette.dropShadow
}
}
contentItem: ListView {
id: userListView
anchors.left: parent.left
anchors.right: parent.right
height: (count * 64) > parent.height ? parent.height : (count * 64)
clip: true
model: contactsModel
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded
}
boundsBehavior: Flickable.StopAtBounds
delegate: Item {
id: wrapper
anchors.right: parent.right
anchors.left: parent.left
height: 64
property bool hovered: false
Rectangle {
id: rectangle
anchors.fill: parent
anchors.topMargin: 8
anchors.rightMargin: 8
anchors.leftMargin: 8
radius: 8
visible: (tagSelector.sortedList.count > 0)
color: (wrapper.hovered) ? Theme.palette.baseColor2 : "transparent"
}
StatusSmartIdenticon {
id: contactImage
anchors.left: parent.left
anchors.leftMargin: 16//Style.current.padding
anchors.verticalCenter: parent.verticalCenter
name: model.name
icon: StatusIconSettings {
width: 28
height: 28
letterSize: 15
}
image: StatusImageSettings {
width: 28
height: 28
source: model.icon
isIdenticon: model.isIdenticon
}
}
StatusBaseText {
id: contactInfo
text: model.name
anchors.right: parent.right
anchors.rightMargin: 8
anchors.left: contactImage.right
anchors.leftMargin: 16
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
color: Theme.palette.directColor1
font.weight: Font.Medium
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
anchors.fill: parent
hoverEnabled: true
onEntered: {
wrapper.hovered = true;
}
onExited: {
wrapper.hovered = false;
}
onClicked: {
tagSelector.insertTag(model.name, model.publicId);
}
}
}
}
}
Component.onCompleted: {
if (visible) {
tagSelector.textEdit.forceActiveFocus();
}
}
}
StatusBaseText {
visible: (contactsModel.count === 0)
@@ -266,8 +266,6 @@ StatusAppThreePanelLayout {
image.source: model.source
image.isIdenticon: model.isIdenticon
isOnline: model.isOnline
ringSettings.ringSpecModel: model.ringSpecModel
ringSettings.distinctiveColors: Theme.palette.identiconRingColors
}
}
}
+22 -58
View File
@@ -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,66 +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
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
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
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
}
}
-15
View File
@@ -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"
@@ -270,11 +265,6 @@ StatusWindow {
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusWizardStepper"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusListSectionHeadline { text: "StatusQ.Popup" }
StatusNavigationListItem {
title: "StatusPopupMenu"
@@ -293,11 +283,6 @@ StatusWindow {
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusColorSelectorGrid"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
}
}
}
@@ -1,36 +0,0 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
Item {
id: root
width: 800
height: 100
Row {
id: selectedColor
anchors.top: parent.top
anchors.left: colorSelectionGrid.left
spacing: 10
StatusBaseText {
text: "SelectedColor is"
}
Rectangle {
width: 100
height: 20
radius: width/2
color: colorSelectionGrid.selectedColor
}
}
StatusColorSelectorGrid {
id: colorSelectionGrid
anchors.top: selectedColor.bottom
anchors.topMargin: 10
anchors.horizontalCenter: parent.horizontalCenter
titleText: "COLOR"
selectedColorIndex: 2
}
}
+1 -83
View File
@@ -57,33 +57,6 @@ Column {
input.clearable: true
}
Item {
implicitWidth: 480
implicitHeight: 102
z: 100000
StatusSeedPhraseInput {
id: statusSeedInput
anchors.left: parent.left
anchors.right: parent.right
textEdit.input.anchors.leftMargin: 16
textEdit.input.anchors.rightMargin: 16
textEdit.input.anchors.topMargin: 11
textEdit.label: "Input with drop down selection list"
leftComponentText: "1"
inputList: ListModel {
ListElement {
seedWord: "panda"
}
ListElement {
seedWord: "posible"
}
ListElement {
seedWord: "wing"
}
}
}
}
StatusInput {
label: "Label"
charLimit: 30
@@ -129,24 +102,10 @@ Column {
]
}
StatusInput {
label: "Input with <i>StatusRegularExpressionValidator</i>"
charLimit: 30
input.placeholderText: `Must match regex(${validators[0].regularExpression.toString()}) and <= 30 chars`
validationMode: StatusInput.ValidationMode.IgnoreInvalidInput
validators: [
StatusRegularExpressionValidator {
regularExpression: /^[0-9A-Za-z_\$-\s]*$/
errorMessage: "Bad input!"
}
]
}
StatusInput {
label: "Label"
input.placeholderText: "Input width component (right side)"
input.rightComponent: StatusIcon {
input.component: StatusIcon {
icon: "cancel"
height: 16
color: Theme.palette.dangerColor1
@@ -171,45 +130,4 @@ Column {
input.minimumHeight: 80
input.maximumHeight: 200
}
StatusInput {
property bool toggled: true
label: "Input with emoji icon"
input.placeholderText: "Enter Name"
input.icon.emoji: toggled ? "😁" : "🧸"
input.icon.color: "blue"
input.isIconSelectable: true
onIconClicked: {
toggled = !toggled
}
}
StatusInput {
property bool toggled: true
label: "Input with selectable icon which is not an emoji"
input.placeholderText: "Enter Name"
input.icon.emoji: ""
input.icon.name: toggled ? "filled-account" : "image"
input.icon.color: "blue"
input.isIconSelectable: true
onIconClicked: {
toggled = !toggled
}
}
StatusInput {
label: "Input with inline token selector"
input.leftComponent: StatusTokenInlineSelector {
tokens: [{amount: 0.1, token: "ETH"},
{amount: 10, token: "SNT"},
{amount: 15, token: "MANA"}]
StatusToolTip {
id: toolTip
text: "posted"
}
onTriggered: toolTip.visible = true
}
input.edit.readOnly: true
}
}
-75
View File
@@ -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 -1
View File
@@ -51,6 +51,6 @@ Item {
anchors.centerIn: parent
namesModel: root.asortedContacts
toLabelText: qsTr("To: ")
warningText: qsTr("USER LIMIT REACHED")
warningText: qsTr("5 USER LIMIT REACHED")
}
}
-100
View File
@@ -1,100 +0,0 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
Item {
id: root
width: 800
height: 100
//Simulate animation between steps
property bool stepsCompleted: false
function reset() {
for (var i = 0; i < stepsListModel.count; i++) {
stepsListModel.setProperty(i, "loading", false);
stepsListModel.setProperty(i, "stepCompleted", false);
step1.loadingTime = 0;
step2.loadingTime = 0;
root.stepsCompleted = false;
}
}
ListModel {
id: stepsListModel
ListElement {description:"Send Request"; loadingTime: 0; stepCompleted: false}
ListElement {description:"Receive Response"; loadingTime: 0; stepCompleted: false}
ListElement {description:"Confirm Identity"; loadingTime: 0; stepCompleted: false}
}
Shortcut {
sequence: "Ctrl+R"
onActivated: {
if (!root.stepsCompleted) {
animate.running = true;
} else {
root.reset();
}
}
}
StatusBaseText {
id: indicLabel
anchors.horizontalCenter: parent.horizontalCenter
color: Theme.palette.directColor1
text: "Press Ctrl+R to run the animation"
font.pixelSize: 17
}
SequentialAnimation {
id: animate
ScriptAction {
id: step1
property int loadingTime: 0
Behavior on loadingTime { NumberAnimation { duration: 2000 }}
onLoadingTimeChanged: {
stepsListModel.setProperty(1, "loadingTime", step1.loadingTime);
}
script: {
step1.loadingTime = 2000;
stepsListModel.setProperty(0, "loadingTime", step1.loadingTime);
stepsListModel.setProperty(0, "stepCompleted", true);
}
}
PauseAnimation {
duration: 2100
}
ScriptAction {
id: step2
property int loadingTime: 0
Behavior on loadingTime { NumberAnimation { duration: 2000 } }
onLoadingTimeChanged: {
stepsListModel.setProperty(2, "loadingTime", step2.loadingTime);
}
script: {
step2.loadingTime = 2000;
stepsListModel.setProperty(1, "stepCompleted", true);
}
}
PauseAnimation {
duration: 2100
}
ScriptAction {
script: {
stepsListModel.setProperty(2, "stepCompleted", true);
root.stepsCompleted = true;
}
}
}
//simulation code
StatusWizardStepper {
id: wizardStepper
width: (parent.width - 50)
anchors.top: indicLabel.bottom
anchors.topMargin: 16
anchors.horizontalCenter: parent.horizontalCenter
stepsModel: stepsListModel
}
}
+1 -1
View File
@@ -15,7 +15,7 @@ SOURCES += \
handler.cpp \
main.cpp \
sandboxapp.cpp \
spellchecker.cpp \
spellchecker.cpp
!macx {
SOURCES += statuswindow.cpp
+3 -9
View File
@@ -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
+1 -5
View File
@@ -15,7 +15,7 @@ Column {
width: 288
property string categoryId: ""
property var model: null
property var model: []
property bool draggableItems: false
property alias statusChatListItems: statusChatListItems
@@ -97,12 +97,10 @@ Column {
chatId: model.itemId
categoryId: model.parentItemId? model.parentItemId : ""
name: model.name
icon.emoji: model.emoji
type: !!model.type ? model.type : StatusChatListItem.Type.CommunityChat
muted: model.muted
hasUnreadMessages: model.hasUnreadMessages
notificationsCount: model.notificationsCount
highlightWhenCreated: !!model.highlight
selected: model.active
icon.color: model.color
image.isIdenticon: model.isIdenticon
@@ -110,8 +108,6 @@ Column {
sensor.cursorShape: dragSensor.cursorShape
onClicked: {
highlightWhenCreated = false
if (mouse.button === Qt.RightButton && !!statusChatList.popupMenu) {
statusChatListItem.highlighted = true
@@ -48,6 +48,7 @@ Column {
popupMenuSlot.item.popup(mouse.x + 4, mouse.y + 6);
return
}
statusChatListCategory.opened = !opened;
}
}
onTitleClicked: statusChatListCategory.opened = !opened
@@ -5,7 +5,6 @@ import QtGraphicalEffects 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
@@ -29,14 +28,10 @@ Rectangle {
width: 24
height: 24
color: Theme.palette.miscColor5
letterSize: emoji ? 11 : 15
emoji: ""
emojiSize: Emoji.size.verySmall
charactersLen: 1
letterSize: 15
}
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
@@ -150,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
}
@@ -14,7 +14,6 @@ StatusListItem {
components: [
StatusBadge {
visible: statusContactRequestsListItem.requestsCount > 0
value: statusContactRequestsListItem.requestsCount
anchors.verticalCenter: parent.verticalCenter
border.width: 4
@@ -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
}
}
@@ -12,7 +12,6 @@ Rectangle {
property alias additionalText: additionalText.text
property alias button: button
property alias expandableComponent: expandableRegion.sourceComponent
property alias expandableItem: expandableRegion.item
property int type: StatusExpandableItem.Type.Primary
property bool expandable: true
@@ -186,7 +185,7 @@ Rectangle {
anchors.leftMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 48 : 0
anchors.right: parent.right
anchors.rightMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 16 : 0
visible: false
active: false
}
onExpandedChanged: {
@@ -203,13 +202,13 @@ Rectangle {
name: "EXPANDED"
PropertyChanges {target: expandImage; icon: "chevron-up"}
PropertyChanges {target: statusExpandableItem; height: 82 + expandableRegion.height + 22}
PropertyChanges {target: expandableRegion; visible: true}
PropertyChanges {target: expandableRegion; active: true}
},
State {
name: "COLLAPSED"
PropertyChanges {target: expandImage; icon: "chevron-down"}
PropertyChanges {target: statusExpandableItem; height: 82}
PropertyChanges {target: expandableRegion; visible: false}
PropertyChanges {target: expandableRegion; active: false}
}
]
@@ -1,17 +1,13 @@
import QtQuick 2.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
Rectangle {
id: root
id: statusLetterIdenticon
property alias identiconText: identiconText
property string name
property string emoji
property string emojiSize
property int letterSize: 21
property int charactersLen: 1
color: Theme.palette.miscColor5
width: 40
@@ -20,30 +16,15 @@ Rectangle {
StatusBaseText {
id: identiconText
anchors.alignWhenCentered: false
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
width: parent.width
height: parent.height
text: ((statusLetterIdenticon.name.charAt(0) === "#")
|| (statusLetterIdenticon.name.charAt(0) === "@") ?
statusLetterIdenticon.name.charAt(1) : statusLetterIdenticon.name.charAt(0)).toUpperCase()
font.weight: Font.Bold
font.pixelSize: root.letterSize
font.pixelSize: statusLetterIdenticon.letterSize
color: Qt.rgba(255, 255, 255, 0.7)
text: {
if (emoji) {
if(Utils.isHtml(emoji))
return emoji
else
return Emoji.parse(emoji, emojiSize || undefined)
}
const shift = (root.name.charAt(0) === "#") ||
(root.name.charAt(0) === "@")
return root.name.substring(shift, shift + charactersLen).toUpperCase()
}
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
}
+68 -81
View File
@@ -13,20 +13,16 @@ 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: ""
property real leftPadding: 16
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
property var bottomModel: []
property Component bottomDelegate
property var tagsModel: []
property Component tagsDelegate
property StatusIconSettings icon: StatusIconSettings {
height: isLetterIdenticon ? 40 : 20
@@ -34,7 +30,6 @@ Rectangle {
rotation: 0
isLetterIdenticon: false
letterSize: 21
charactersLen: 1
color: isLetterIdenticon ? background.color : type === StatusListItem.Type.Danger ?
Theme.palette.dangerColor1 : Theme.palette.primaryColor1
background: StatusIconBackgroundSettings {
@@ -56,10 +51,31 @@ Rectangle {
height: 40
isIdenticon: false
}
property StatusIdenticonRingSettings ringSettings: StatusIdenticonRingSettings {
initalAngleRad: 0
ringPxSize: 1.5
distinctiveColors: Theme.palette.identiconRingColors
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
@@ -67,13 +83,10 @@ 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
property alias statusListItemComponentsSlot: statusListItemComponentsSlot
property alias statusListItemTagsSlot: statusListItemTagsSlot
property alias statusListItemInlineTagsSlot: statusListItemTagsSlotInline
signal clicked(string itemId)
signal titleClicked(string titleId)
@@ -85,14 +98,9 @@ Rectangle {
}
implicitWidth: 448
implicitHeight: {
if (bottomModel.length === 0) {
return Math.max(64, statusListItemTitleArea.height + 16)
}
return Math.max(64, statusListItemTitleArea.height + 90)
}
implicitHeight: Math.max(64, statusListItemTitleArea.height + 16)
color: {
if (sensor.containsMouse || statusListItem.highlighted) {
if (sensor.containsMouse) {
switch(type) {
case StatusListItem.Type.Primary:
return Theme.palette.baseColor2
@@ -141,26 +149,16 @@ 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: bottomModel.length === 0 ? parent.verticalCenter : undefined
anchors.verticalCenter: parent.verticalCenter
height: childrenRect.height
StatusBaseText {
@@ -170,9 +168,8 @@ Rectangle {
height: visible ? contentHeight : 0
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
anchors.left: parent.left
anchors.right: !statusListItem.titleAsideText && !titleIconsRow.sourceComponent ? parent.right : undefined
anchors.top: bottomModel.length === 0 ? undefined: parent.top
anchors.topMargin: bottomModel.length === 0 ? undefined : 20
anchors.right: !statusListItem.titleAsideText && !statusListItem.titleIcon1Visible && !statusListItem.titleIcon2Visible
? parent.right : undefined
color: {
if (!statusListItem.enabled) {
return Theme.palette.baseColor1
@@ -189,10 +186,9 @@ Rectangle {
MouseArea {
anchors.fill: parent
enabled: statusListItem.enabled
cursorShape: sensor.enabled && containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
cursorShape: containsMouse? Qt.PointingHandCursor : Qt.ArrowCursor
hoverEnabled: true
propagateComposedEvents: statusListItem.propagateTitleClicks
propagateComposedEvents: true
onClicked: {
statusListItem.titleClicked(statusListItem.titleId)
mouse.accepted = false
@@ -205,20 +201,43 @@ Rectangle {
anchors.left: statusListItemTitle.right
anchors.leftMargin: 4
anchors.verticalCenter: statusListItemTitle.verticalCenter
anchors.top: bottomModel.length === 0 ? undefined: parent.top
anchors.topMargin: bottomModel.length === 0 ? undefined : 20
text: statusListItem.titleAsideText
font.pixelSize: 10
color: Theme.palette.baseColor1
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
@@ -250,42 +269,11 @@ Rectangle {
width: contentItem.width
implicitHeight: visible ? 22 : 0
}
Row {
id: statusListItemTagsSlotInline
anchors.top: statusListItemTertiaryTitle.bottom
width: parent.width
spacing: 10
clip: true
Repeater {
model: tagsModel
delegate: tagsDelegate
}
}
}
Row {
id: statusListItemTagsSlot
anchors.topMargin: 16
anchors.top: iconOrImage.bottom
anchors.left: parent.left
anchors.leftMargin: 16
width: statusListItemBadge.width
spacing: 10
anchors.verticalCenter: parent.verticalCenter
Repeater {
model: bottomModel
delegate: bottomDelegate
}
}
StatusBaseText {
id: statusListItemLabel
anchors.verticalCenter: bottomModel.length === 0 ? parent.verticalCenter : undefined
anchors.top: bottomModel.length === 0 ? undefined: parent.top
anchors.topMargin: bottomModel.length === 0 ? undefined : 16
anchors.verticalCenter: parent.verticalCenter
anchors.right: statusListItemComponentsSlot.left
anchors.rightMargin: statusListItemComponentsSlot.width > 0 ? 10 : 0
@@ -295,13 +283,12 @@ Rectangle {
visible: !!statusListItem.label
}
Row {
id: statusListItemComponentsSlot
anchors.right: parent.right
anchors.rightMargin: statusListItem.rightPadding
anchors.verticalCenter: bottomModel.length === 0 ? parent.verticalCenter : undefined
anchors.top: bottomModel.length === 0 ? undefined: parent.top
anchors.topMargin: bottomModel.length === 0 ? undefined : 12
anchors.verticalCenter: parent.verticalCenter
spacing: 10
}
}
@@ -57,8 +57,6 @@ Control {
visible: root.icon.isLetterIdenticon
color: root.icon.color
name: root.primaryText
emoji: root.icon.emoji
emojiSize: root.icon.emojiSize
}
StatusBaseText {
font.weight: Font.Medium
@@ -1,81 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Rectangle {
id: root
width: layout.width
height: 30
color: Theme.palette.primaryColor3
radius: 15
property alias titleText: titleText
property string title: ""
property bool closeButtonVisible: true
signal clicked()
property StatusImageSettings image: StatusImageSettings {
width: 20
height: 20
isIdenticon: false
}
property StatusIconSettings icon: StatusIconSettings {
height: 20
width: 20
rotation: 0
isLetterIdenticon: false
letterSize: 10
color: Theme.palette.primaryColor1
background: StatusIconBackgroundSettings {
width: 15
height: 15
color: Theme.palette.primaryColor3
}
}
RowLayout {
id: layout
height: parent.height
spacing: 5
StatusSmartIdenticon {
id: iconOrImage
Layout.leftMargin: 5
image: root.image
icon: root.icon
name: root.title
active: root.icon.isLetterIdenticon ||
!!root.icon.name ||
!!root.image.source.toString()
}
StatusBaseText {
id: titleText
color: Theme.palette.primaryColor1
text: root.title
Layout.rightMargin: closeButtonVisible ? 0 : 5
}
StatusIcon {
id: closeIcon
color: Theme.palette.primaryColor1
icon: "close-circle"
visible: closeButtonVisible
Layout.rightMargin: 5
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.clicked()
}
}
}
}
}
@@ -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
}
+13 -2
View File
@@ -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
@@ -15,7 +13,6 @@ Loader {
property StatusIconSettings icon: StatusIconSettings {
width: 40
height: 40
charactersLen: 1
}
property StatusImageSettings image: StatusImageSettings {
@@ -23,12 +20,6 @@ Loader {
height: 40
}
property StatusIdenticonRingSettings ringSettings: StatusIdenticonRingSettings {
initalAngleRad: 0
ringPxSize: 1.5
distinctiveColors: Theme.palette.identiconRingColors
}
sourceComponent: statusSmartIdenticon.icon.isLetterIdenticon ? letterIdenticon :
!!statusSmartIdenticon.image.source.toString() ? roundedImage :
!!statusSmartIdenticon.icon.name.toString() ? roundedIcon : letterIdenticon
@@ -84,21 +75,10 @@ Loader {
height: statusSmartIdenticon.icon.height
color: statusSmartIdenticon.icon.color
name: statusSmartIdenticon.name
emoji: statusSmartIdenticon.icon.emoji
emojiSize: statusSmartIdenticon.icon.emojiSize
letterSize: statusSmartIdenticon.icon.letterSize
identiconText.color: statusSmartIdenticon.icon.textColor
charactersLen: statusSmartIdenticon.icon.charactersLen
}
}
// Next components are painted above main sourceComponent
StatusIdenticonRing {
settings: statusSmartIdenticon.ringSettings
anchors.fill: parent
z: statusSmartIdenticon.dZ/2
}
// State component
StatusBadge {
id: statusBadge
@@ -108,6 +88,6 @@ Loader {
border.width: 3
implicitHeight: 15
implicitWidth: 15
z: statusSmartIdenticon.dZ
z: 100
}
}
+44 -203
View File
@@ -1,7 +1,6 @@
import QtQuick 2.14
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.14
import QtGraphicalEffects 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
@@ -10,57 +9,29 @@ Item {
id: root
implicitWidth: 448
implicitHeight: 44 + ((userListView.count > 0) ? 44 + ((((userListView.count * 64) > root.maxHeight)
? root.maxHeight : (userListView.count * 64))) :0)
implicitHeight: 44
property real maxHeight
property alias textEdit: edit
property alias text: edit.text
property string warningText: ""
property string toLabelText: ""
property string listLabel: ""
property int nameCountLimit: 5
property ListModel sortedList: ListModel { }
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();
}
}
function sortModel(inputModel) {
sortedList.clear();
if (text !== "") {
for (var i = 0; i < inputModel.count; i++ ) {
var entry = inputModel.get(i);
if (entry.name.toLowerCase().includes(text.toLowerCase())) {
sortedList.insert(sortedList.count, {"publicId": entry.publicId, "name": entry.name,
"icon": entry.icon, "isIdenticon": entry.isIdenticon,
"onlineStatus": entry.onlineStatus});
userListView.model = sortedList;
}
}
} else {
userListView.model = inputModel;
}
}
signal addMember(string memberId)
signal removeMember(string memberId)
Rectangle {
id: tagSelectorRect
width: parent.width
height: 44
anchors.fill: parent
radius: 8
color: Theme.palette.baseColor2
@@ -76,54 +47,47 @@ Item {
text: root.toLabelText
}
ScrollView {
Layout.preferredWidth: (namesList.contentWidth > (parent.width - 142)) ?
(parent.width - 142) : namesList.contentWidth
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
onCountChanged: {
contentX = contentWidth;
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);
}
}
}
@@ -142,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);
}
}
@@ -151,134 +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
}
}
}
StatusBaseText {
id: contactsLabel
font.pixelSize: 15
anchors.left: parent.left
anchors.leftMargin: 8
anchors.top: tagSelectorRect.bottom
anchors.topMargin: 32
visible: (namesModel.count === 0)
color: Theme.palette.baseColor1
text: root.listLabel
}
Control {
id: suggestionsContainer
width: 360
anchors {
top: (root.sortedList.count > 0) ? tagSelectorRect.bottom : contactsLabel.bottom
topMargin: 8//Style.current.padding
bottom: parent.bottom
bottomMargin: 20//Style.current.bigPadding
}
visible: ((root.namesModel.count === 0) || (root.sortedList.count > 0))
x: ((root.namesModel.count > 0) && ((edit.x + 8) <= (root.width - suggestionsContainer.width)))
? (edit.x + 8) : 0
background: Rectangle {
id: bgRect
anchors.fill: parent
visible: (root.sortedList.count > 0)
color: Theme.palette.statusPopupMenu.backgroundColor
radius: 8
layer.enabled: true
layer.effect: DropShadow {
width: bgRect.width
height: bgRect.height
x: bgRect.x
source: bgRect
horizontalOffset: 0
verticalOffset: 4
radius: 12
samples: 25
spread: 0.2
color: Theme.palette.dropShadow
}
}
contentItem: ListView {
id: userListView
anchors.fill: parent
anchors.topMargin: 8
anchors.bottomMargin: 8
clip: true
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded
}
boundsBehavior: Flickable.StopAtBounds
delegate: Item {
id: wrapper
anchors.right: parent.right
anchors.left: parent.left
height: 64
property bool hovered: false
Rectangle {
id: rectangle
anchors.fill: parent
anchors.rightMargin: 8
anchors.leftMargin: 8
radius: 8
visible: (root.sortedList.count > 0)
color: (wrapper.hovered) ? Theme.palette.baseColor2 : "transparent"
}
StatusSmartIdenticon {
id: contactImage
anchors.left: parent.left
anchors.leftMargin: 16//Style.current.padding
anchors.verticalCenter: parent.verticalCenter
name: model.name
icon: StatusIconSettings {
width: 40
height: 40
letterSize: 15
}
image: StatusImageSettings {
width: 40
height: 40
source: model.icon
isIdenticon: model.isIdenticon
}
}
StatusBaseText {
id: contactInfo
text: model.name
anchors.right: parent.right
anchors.rightMargin: 8
anchors.left: contactImage.right
anchors.leftMargin: 16
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
color: Theme.palette.directColor1
font.weight: Font.Medium
font.pixelSize: 15
}
MouseArea {
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
hoverEnabled: true
onEntered: {
wrapper.hovered = true;
}
onExited: {
wrapper.hovered = false;
}
onClicked: {
root.insertTag(model.name, model.publicId);
}
}
text: root.warningText
}
}
}
@@ -168,11 +168,8 @@ Control {
}
}
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
icon.name: "close"
icon.color: Theme.palette.directColor1
implicitWidth: 30
implicitHeight: 30
onClicked: {
root.open = false;
}
@@ -1,78 +0,0 @@
import QtQuick 2.14
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.14
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
Item {
id: wizardWrapper
width: parent.width
height: 56
property ListModel stepsModel: ListModel { }
ListView {
id: repeat
width: childrenRect.width
height: parent.height
anchors.horizontalCenter: parent.horizontalCenter
orientation: ListView.Horizontal
model: stepsModel
delegate: Item {
id: wrapperItem
width: (index === 0) ? descriptionLabel.contentWidth : (wizardWrapper.width / repeat.count)
height: 56
onXChanged: {
//as x changes while delegates are created, direct assignment doesn't work
x = (index === (repeat.count-1)) ? (width+32) : (label.width/2) + 8
}
StatusProgressBar {
id: barBorder
width: visible ? (parent.width - (label.width/2 + 24)) : 0
height: visible ? 8 : 0
visible: (index > 0)
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -12
from: 0
//TODO what is to: here?
to: 2000
value: loadingTime
backgroundColor: "transparent"
backgroundBorderColor: Theme.palette.primaryColor1
fillColor: Theme.palette.primaryColor1
}
Item {
id: label
width: descriptionLabel.contentWidth
height: 56
anchors.left: (index > 0) ? barBorder.right : parent.left
anchors.leftMargin: (index > 0) ? -((width/2) - 24) : 0
Rectangle {
width: 32
height: 32
anchors.horizontalCenter: parent.horizontalCenter
radius: width/2
color: stepCompleted ? Theme.palette.primaryColor1 : "transparent"
border.color: (stepCompleted && (barBorder.visible ? (barBorder.value === barBorder.to) : true))
? "transparent" : Theme.palette.primaryColor1
border.width: 2
StatusBaseText {
anchors.centerIn: parent
text: index+1
font.pixelSize: 17
color: (stepCompleted && (barBorder.visible ? (barBorder.value === barBorder.to) : true))
? Theme.palette.indirectColor1 : Theme.palette.primaryColor1
}
}
StatusBaseText {
id: descriptionLabel
anchors.bottom: parent.bottom
text: description
color: Theme.palette.directColor1
font.pixelSize: 13
}
}
}
}
}
@@ -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
-3
View File
@@ -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
@@ -23,11 +22,9 @@ StatusRoundIcon 0.1 StatusRoundIcon.qml
StatusRoundedImage 0.1 StatusRoundedImage.qml
StatusMacWindowButtons 0.1 StatusMacWindowButtons.qml
StatusListItemBadge 0.1 StatusListItemBadge.qml
StatusListItemTag 0.1 StatusListItemTag.qml
StatusExpandableItem 0.1 StatusExpandableItem.qml
StatusSmartIdenticon 0.1 StatusSmartIdenticon.qml
StatusMessage 0.1 StatusMessage.qml
StatusMessageDetails 0.1 StatusMessageDetails.qml
StatusTagSelector 0.1 StatusTagSelector.qml
StatusToastMessage 0.1 StatusToastMessage.qml
StatusWizardStepper 0.1 StatusWizardStepper.qml
+150 -189
View File
@@ -1,15 +1,14 @@
import QtQuick 2.14
import QtQuick.Controls 2.14 as QC
import QtQuick.Layouts 1.14
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Item {
id: root
id: statusBaseInput
property bool multiline: false
@@ -25,7 +24,6 @@ Item {
property alias edit: edit
property alias text: edit.text
property alias background: background
property alias color: edit.color
property alias font: edit.font
@@ -37,11 +35,10 @@ Item {
property alias placeholderTextColor: placeholder.color
property alias placeholderFont: placeholder.font
property real leftPadding: leftComponentLoader.item ? 8 : 16
property real leftPadding: 16
property real rightPadding: 16
property real topPadding: 12
property real bottomPadding: 12
property var tabNavItem: null
property real minimumHeight: 0
property real maximumHeight: 0
@@ -52,64 +49,56 @@ Item {
property bool dirty: false
property bool pending: false
property bool leftIcon: true
property bool isIconSelectable: false
property bool showBackground: true
property StatusIconSettings icon: StatusIconSettings {
width: 24
height: 24
name: ""
color: Theme.palette.baseColor1
emoji: ""
letterSize: emoji ? 11 : 14
background: StatusIconBackgroundSettings {
width: 30
height: 30
color: Theme.palette.indirectColor1
}
property Item component
onClearableChanged: {
if (clearable && !component) {
clearButtonLoader.active = true
clearButtonLoader.parent = statusBaseInputComponentSlot
} else {
clearButtonLoader.active = false
}
}
property Component leftComponent
property Component rightComponent
signal iconClicked
signal keyPressed(var event)
signal editClicked()
onComponentChanged: {
if (!!component) {
component.parent = statusBaseInputComponentSlot
}
}
implicitWidth: 448
implicitHeight: multiline ? Math.min(Math.max(
(edit.implicitHeight + topPadding + bottomPadding),
44, root.minimumHeight), root.maximumHeight) : 44
implicitHeight: multiline ? Math.max((edit.implicitHeight + topPadding + bottomPadding), 44) : 44
Rectangle {
id: background
width: parent.width
height: maximumHeight != 0 ? Math.min(
minimumHeight
!= 0 ? Math.max(
root.implicitHeight,
minimumHeight) : root.implicitHeight,
maximumHeight) : parent.height
color: root.showBackground ? Theme.palette.baseColor2
: "transparent"
minimumHeight != 0 ? Math.max(statusBaseInput.implicitHeight, minimumHeight)
: statusBaseInput.implicitHeight, maximumHeight) : parent.height
color: Theme.palette.baseColor2
radius: 8
clip: true
border.width: 1
border.color: {
if (!root.showBackground) {
return "transparent"
}
if (!root.valid && root.dirty) {
return Theme.palette.dangerColor1
if (!statusBaseInput.valid && statusBaseInput.dirty) {
return Theme.palette.dangerColor1;
}
if (edit.activeFocus) {
return Theme.palette.primaryColor1
return Theme.palette.primaryColor1;
}
return sensor.containsMouse ? Theme.palette.primaryColor2 : "transparent"
}
MouseArea {
id: sensor
enabled: !edit.activeFocus
@@ -118,138 +107,146 @@ Item {
cursorShape: Qt.IBeamCursor
onClicked: {
edit.forceActiveFocus()
root.editClicked()
}
RowLayout {
anchors {
fill: parent
leftMargin: root.leftPadding
rightMargin: root.rightPadding
}
StatusIcon {
id: statusIcon
anchors.topMargin: 10
anchors.left: statusBaseInput.leftIcon ? parent.left : undefined
anchors.right: !statusBaseInput.leftIcon ? parent.right : undefined
anchors.leftMargin: 10
anchors.rightMargin: 10
anchors.verticalCenter: parent.verticalCenter
icon: statusBaseInput.icon.name
width: statusBaseInput.icon.width
height: statusBaseInput.icon.height
color: statusBaseInput.icon.color
visible: !!statusBaseInput.icon.name
}
Flickable {
id: flick
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: (statusIcon.visible && statusBaseInput.leftIcon) ?
statusIcon.right : parent.left
anchors.right: {
if (!!statusBaseInput.component) {
return statusBaseInputComponentSlot.left
}
return statusIcon.visible && !statusBaseInput.leftIcon ? statusIcon.left : parent.right
}
anchors.leftMargin: statusIcon.visible && statusBaseInput.leftIcon ? 8
: statusBaseInput.leftPadding
anchors.rightMargin: {
return clearable ? clearButtonLoader.width + 12 :
(statusIcon.visible && !leftIcon) || !!statusBaseInput.component ? 8 : 0
}
contentWidth: edit.paintedWidth
contentHeight: edit.paintedHeight
boundsBehavior: Flickable.StopAtBounds
QC.ScrollBar.vertical: QC.ScrollBar { interactive: multiline; enabled: multiline }
clip: true
Loader {
id: leftComponentLoader
sourceComponent: {
if (root.leftComponent) return root.leftComponent
if (!root.leftIcon) return undefined
if (root.icon.emoji) return identiconComponent
if (root.icon.name) return isIconSelectable ? identiconComponent : iconComponent
return undefined
}
function ensureVisible(r) {
if (contentX >= r.x)
contentX = r.x;
else if (contentX+width <= r.x+r.width)
contentX = r.x+r.width-width;
if (contentY >= r.y)
contentY = r.y;
else if (contentY+height <= r.y+r.height)
contentY = r.y+r.height-height;
}
Flickable {
id: flick
Layout.fillHeight: true
Layout.fillWidth: true
Layout.topMargin: root.topPadding
Layout.bottomMargin: root.bottomPadding
contentWidth: edit.paintedWidth
contentHeight: edit.paintedHeight
boundsBehavior: Flickable.StopAtBounds
QC.ScrollBar.vertical: QC.ScrollBar {
interactive: multiline
enabled: multiline
}
clip: true
function ensureVisible(r) {
if (contentX >= r.x)
contentX = r.x
else if (contentX + width <= r.x + r.width)
contentX = r.x + r.width - width
if (contentY >= r.y)
contentY = r.y
else if (contentY + height <= r.y + r.height)
contentY = r.y + r.height - height
}
TextEdit {
id: edit
property string previousText: text
property var keyEvent
width: flick.width
height: flick.height
verticalAlignment: Text.AlignVCenter
selectByMouse: true
selectionColor: Theme.palette.primaryColor2
selectedTextColor: color
focus: true
font.pixelSize: 15
font.family: Theme.palette.baseFont.name
color: Theme.palette.directColor1
wrapMode: root.multiline ? Text.WrapAtWordBoundaryOrAnywhere : TextEdit.NoWrap
Keys.onReturnPressed: event.accepted = !multiline
Keys.onEnterPressed: event.accepted = !multiline
Keys.forwardTo: [root]
KeyNavigation.priority: !!root.tabNavItem ? KeyNavigation.BeforeItem : KeyNavigation.AfterItem
KeyNavigation.tab: root.tabNavItem
Keys.onPressed: {
edit.keyEvent = event.key
root.keyPressed(event);
TextEdit {
id: edit
property string previousText: text
width: flick.width
height: flick.height
verticalAlignment: Text.AlignVCenter
selectByMouse: true
selectionColor: Theme.palette.primaryColor2
selectedTextColor: color
focus: true
font.pixelSize: 15
font.family: Theme.palette.baseFont.name
color: Theme.palette.directColor1
onCursorRectangleChanged: { flick.ensureVisible(cursorRectangle); }
wrapMode: statusBaseInput.multiline ? Text.WrapAtWordBoundaryOrAnywhere : TextEdit.NoWrap
onActiveFocusChanged: {
if (statusBaseInput.pristine) {
statusBaseInput.pristine = false
}
}
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
onActiveFocusChanged: if (root.pristine) root.pristine = false
onTextChanged: {
root.dirty = true
if (root.maximumLength > 0) {
if (text.length > root.maximumLength) {
var cursor = cursorPosition
text = previousText
if (cursor > text.length) {
cursorPosition = text.length
} else {
cursorPosition = cursor - 1
}
Keys.onReturnPressed: {
if (multiline) {
event.accepted = false
} else {
event.accepted = true
}
}
Keys.onEnterPressed: {
if (multiline) {
event.accepted = false
} else {
event.accepted = true
}
}
Keys.forwardTo: [statusBaseInput]
onTextChanged: {
statusBaseInput.dirty = true
if (statusBaseInput.maximumLength > 0) {
if (text.length > statusBaseInput.maximumLength) {
var cursor = cursorPosition;
text = previousText;
if (cursor > text.length) {
cursorPosition = text.length;
} else {
cursorPosition = cursor-1;
}
previousText = text
}
}
StatusBaseText {
id: placeholder
visible: (edit.text.length === 0)
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: root.rightPadding
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 15
elide: StatusBaseText.ElideRight
font.family: Theme.palette.baseFont.name
color: root.enabled ? Theme.palette.baseColor1 : Theme.palette.directColor6
previousText = text
}
}
} // Flickable
Loader {
sourceComponent: {
if (root.rightComponent) return root.rightComponent
if (root.clearable) return clearButton
if (root.leftIcon) return undefined
if (root.icon.emoji) return identiconComponent
if (root.icon.name) return isIconSelectable ? identiconComponent : iconComponent
return undefined
StatusBaseText {
id: placeholder
visible: (edit.text.length === 0)
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: statusBaseInput.rightPadding
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 15
elide: StatusBaseText.ElideRight
font.family: Theme.palette.baseFont.name
color: statusBaseInput.enabled ? Theme.palette.baseColor1 :
Theme.palette.directColor6
}
}
} // Flickable
Item {
id: statusBaseInputComponentSlot
anchors.right: parent.right
anchors.rightMargin: 12
width: childrenRect.width
height: childrenRect.height
anchors.verticalCenter: parent.verticalCenter
}
}
} // Rectangle
Component {
id: clearButton
StatusFlatRoundButton {
visible: edit.text.length != 0 && root.clearable && !root.multiline
&& edit.activeFocus
Loader {
id: clearButtonLoader
sourceComponent: StatusFlatRoundButton {
id: clearButton
visible: edit.text.length != 0 &&
statusBaseInput.clearable &&
!statusBaseInput.multiline &&
edit.activeFocus
type: StatusFlatRoundButton.Type.Secondary
width: 24
height: 24
@@ -263,41 +260,5 @@ Item {
}
}
Component {
id: identiconComponent
StatusSmartIdenticon {
id: identicon
icon.width: !root.icon.emoji ? 20 : 30
icon.height: !root.icon.emoji ? 20 : 30
icon.background: root.icon.background
icon.color: root.icon.color
icon.letterSize: root.icon.letterSize
icon.emoji: root.icon.emoji
icon.name: !root.icon.emoji ? root.icon.name : ""
MouseArea {
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
hoverEnabled: true
enabled: identicon.visible
onClicked: root.iconClicked()
}
}
}
Component {
id: iconComponent
StatusIcon {
id: statusIcon
icon: root.icon.name
width: root.icon.width
height: root.icon.height
color: root.icon.color
}
}
}
@@ -1,32 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.14
import StatusQ.Core.Theme 0.1
RadioButton {
id: control
property string radioButtonColor: ""
property string selectionColor: StatusColors.colors['white']
implicitWidth: 48
implicitHeight: 48
indicator: Rectangle {
implicitWidth: 48
implicitHeight: 48
radius: width/2
color: radioButtonColor
Rectangle {
width: 20
height: 20
radius: width/2
color: selectionColor
border.color: StatusColors.colors['grey3']
visible: control.checked
anchors.centerIn: parent
}
}
}
@@ -1,56 +0,0 @@
import QtQuick 2.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import "./"
Column {
id: root
property alias titleText: title.text
property alias title: title
property int selectedColorIndex: 0
property string selectedColor: ""
property var model: [StatusColors.colors['black'],
StatusColors.colors['grey'],
StatusColors.colors['blue2'],
StatusColors.colors['purple'],
StatusColors.colors['cyan'],
StatusColors.colors['violet'],
StatusColors.colors['red2'],
StatusColors.colors['yellow'],
StatusColors.colors['green2'],
StatusColors.colors['moss'],
StatusColors.colors['brown'],
StatusColors.colors['brown2']]
spacing: 16
StatusBaseText {
id: title
verticalAlignment: Text.AlignVCenter
font.pixelSize: 13
color: Theme.palette.baseColor1
}
Grid {
columns: 6
rowSpacing: 16
columnSpacing: 32
Repeater {
model: root.model
delegate: StatusColorRadioButton {
checked: index === selectedColorIndex
radioButtonColor: root.model[index] || "transparent"
onCheckedChanged: {
if(checked) {
selectedColorIndex = index
selectedColor = root.model[index]
}
}
}
}
}
}
@@ -1,132 +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 {
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: root
/*!
\qmlproperty StatusIdenticonRingSettings StatusIdenticonRing::settings
This property holds a set of settings for building the ring.
*/
property StatusIdenticonRingSettings settings: StatusIdenticonRingSettings {
initalAngleRad: 0
ringPxSize: 1.5
}
visible: settings.ringSpecModel !== undefined
Loader {
anchors.fill: parent
active: root.visible
sourceComponent: 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()
}
function getSegmentsCount() {
if (typeof settings.ringSpecModel.count !== "undefined") {
return settings.ringSpecModel.count
}
return settings.ringSpecModel.length
}
function getSegment(i) {
if (typeof settings.ringSpecModel.count !== "undefined") {
return settings.ringSpecModel.get(i)
}
return settings.ringSpecModel[i]
}
function totalRingUnits() {
var units = 0
for (let i=0; i < getSegmentsCount(); i++) {
const segment = getSegment(i)
units += segment.segmentLength
}
return Math.max(1, units)
}
onPaint: {
const context = getContext("2d")
const radius = (height - settings.ringPxSize) / 2
const xPos = width / 2
const yPos = height / 2
const unitRadLen = 2 * Math.PI / totalRingUnits()
const segmentsCount = getSegmentsCount()
let arcPos = settings.initalAngleRad
context.reset()
if(settings.ringSpecModel) {
for (let i=0; i < segmentsCount; i++) {
const segment = getSegment(i)
printArcSegment(context,
xPos,
yPos,
radius,
settings.distinctiveColors[segment.colorId],
arcPos,
segment.segmentLength * unitRadLen,
settings.ringPxSize)
arcPos += segment.segmentLength * unitRadLen
}
}
}
}
}
}
+15 -124
View File
@@ -6,71 +6,27 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Controls.Validators 0.1
/*!
\qmltype StatusInput
\inherits Item
\inqmlmodule StatusQ.Controls
\since StatusQ.Controls 0.1
\brief The StatusInput control provides a generic user text input
Example of how to use it:
\qml
StatusInput {
label: "Label"
charLimit: 30
errorMessage: "Input doesn't match validator"
input.clearable: true
input.placeholderText: "Placeholder text"
}
\endqml
For a list of components available see StatusQ.
*/
Item {
id: root
implicitWidth: 480
implicitHeight: (label.visible ?
label.anchors.topMargin +
label.height :
charLimitLabel.visible ?
charLimitLabel.anchors.topMargin +
charLimitLabel.height :
0) +
statusBaseInput.anchors.topMargin +
statusBaseInput.height +
(errorMessage.visible ?
errorMessage.anchors.topMargin +
errorMessage.height :
0) + 8
height: implicitHeight
width: implicitWidth
height: (label.visible ?
label.anchors.topMargin +
label.height :
charLimitLabel.visible ?
charLimitLabel.anchors.topMargin +
charLimitLabel.height :
0) +
statusBaseInput.anchors.topMargin +
statusBaseInput.height +
(errorMessage.visible ?
errorMessage.anchors.topMargin +
errorMessage.height :
0) + 8
property alias input: statusBaseInput
property alias valid: statusBaseInput.valid
property alias pending: statusBaseInput.pending
property alias text: statusBaseInput.text
/*!
\qmlproperty errorMessageCmp
This property represents the errorMessage shown on statusInput in cases one of the validators fails
This can be used to control the error message's look and position from the outside.
Examples of usage
\qml
StatusInput {
errorMessageCmp.font.pixelSize: 15
errorMessageCmp.font.weight: Font.Medium
}
\endqml
*/
property alias errorMessageCmp: errorMessage
property string label: ""
property string secondaryLabel: ""
property int charLimit: 0
@@ -79,73 +35,27 @@ Item {
property real rightPadding: 16
property list<StatusValidator> validators
property list<StatusAsyncValidator> asyncValidators
/*!
\qmlproperty int (enumeration ValidationMode)
This property describes the validation mode
Note that this property should be always strictly compared with one of ValidationMode's value
Default value: StatusInput.ValidationMode.OnlyWhenDirty
Examples of usage
> To ignore invalid input
\qml
StatusInput {
validationMode: StatusInput.ValidationMode.IgnoreInvalidInput
validators: [
StatusMinLengthValidator {
minLength: 15
}
]
}
\endqml
*/
property int validationMode: StatusInput.ValidationMode.OnlyWhenDirty
property string validatedValue
property var pendingValidators: []
signal iconClicked()
signal keyPressed(var event)
signal editClicked()
/*!
\qmltype ValidationMode
\brief Available validation modes supported by StatusInput
Values:
- OnlyWhenDirty validates input only after it has become dirty
- Always validates input even before it has become dirty
- IgnoreInvalidInput ignore the new content if it doesn't match validators
Has no effect without at least a validator
\note that it represents a QML enumeration and can't be used as a property type, we use int instead
\see validationMode for a usage example
\see validators
*/
enum ValidationMode {
OnlyWhenDirty, // validates input only after it has become dirty
Always, // validates input even before it has become dirty
IgnoreInvalidInput // ignore the new content if it doesn't match
Always // validates input even before it has become dirty
}
property var errors: ({})
property var asyncErrors: ({})
function reset() {
statusBaseInput.valid = true
statusBaseInput.valid = false
statusBaseInput.pristine = true
statusBaseInput.text = ""
root.errorMessage = ""
}
property string _previousText: text
function validate() {
if (!statusBaseInput.dirty && validationMode === StatusInput.ValidationMode.OnlyWhenDirty) {
return
}
@@ -175,23 +85,11 @@ Item {
if (errors){
let errs = Object.values(errors)
if (errs && errs[0]) {
if(validationMode === StatusInput.ValidationMode.IgnoreInvalidInput
&& text.length > _previousText.length) {
// Undo the last input
const cursor = statusBaseInput.cursorPosition;
statusBaseInput.text = _previousText;
if (statusBaseInput.cursor > statusBaseInput.text.length) {
statusBaseInput.cursorPosition = statusBaseInput.text.length;
} else {
statusBaseInput.cursorPosition = cursor-1;
}
}
errorMessage.text = errs[0].errorMessage || root.errorMessage;
} else {
errorMessage.text = ""
}
}
_previousText = text
}
if (asyncValidators.length && !Object.values(errors).length) {
@@ -291,13 +189,6 @@ Item {
onTextChanged: root.validate()
Keys.forwardTo: [root]
onIconClicked: root.iconClicked()
onKeyPressed: {
root.keyPressed(event);
}
onEditChanged: {
root.editClicked();
}
}
StatusBaseText {
@@ -15,23 +15,16 @@ StatusProgressBar {
property string labelGreat: "Great"
enum Strength {
None, // 0
VeryWeak, // 1
Weak, // 2
SoSo, // 3
Good, // 4
Great // 5
VeryWeak, // 0
Weak, // 1
SoSo, // 2
Good, // 3
Great // 4
}
onValueChanged: if(value === 0) control.strength = StatusPasswordStrengthIndicator.Strength.None
// Behavior:
states: [
// Strength states definition:
State {
when: control.strength === StatusPasswordStrengthIndicator.Strength.None
PropertyChanges { target: control; text: ""}
},
State {
when: control.strength === StatusPasswordStrengthIndicator.Strength.VeryWeak
PropertyChanges { target: control; fillColor : Theme.palette.dangerColor1}
-234
View File
@@ -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 } }
}
}
@@ -10,7 +10,6 @@ ProgressBar {
property string text
property color fillColor
property color backgroundColor: Theme.palette.directColor8
property color backgroundBorderColor: "transparent"
width: 416
height: 16
@@ -20,7 +19,6 @@ ProgressBar {
implicitWidth: parent.width
implicitHeight: parent.height
color: control.backgroundColor
border.color: control.backgroundBorderColor
radius: 5
}
contentItem: Item {
@@ -1,141 +0,0 @@
import QtQuick 2.12
import QtGraphicalEffects 1.13
import QtQuick.Controls 2.12
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Item {
id: root
width: 162
height: 44
property alias textEdit: seedWordInput
property alias text: seedWordInput.text
property string leftComponentText: ""
property ListModel inputList: ListModel { }
property ListModel filteredList: ListModel { }
signal doneInsertingWord(string word)
signal keyPressed(var event)
signal editClicked()
onActiveFocusChanged: {
if (root.activeFocus) {
seedWordInput.input.edit.forceActiveFocus();
}
}
StatusInput {
id: seedWordInput
implicitWidth: parent.width
implicitHeight: parent.height
input.anchors.topMargin: 0
input.anchors.leftMargin: 0
input.anchors.rightMargin: 0
input.leftComponent: StatusBaseText {
text: root.leftComponentText
color: seedWordInput.input.edit.activeFocus ?
Theme.palette.primaryColor1 : Theme.palette.baseColor1
font.pixelSize: 15
}
onTextChanged: {
filteredList.clear();
if (text !== "") {
for (var i = 0; i < inputList.count;i++) {
if (inputList.get(i).seedWord.startsWith(text)) {
filteredList.insert(filteredList.count, {"seedWord": inputList.get(i).seedWord});
}
}
seedSuggestionsList.model = filteredList;
if ((text.length === 3) && (filteredList.count === 1) &&
((input.edit.keyEvent !== Qt.Key_Backspace) && (input.edit.keyEvent !== Qt.Key_Delete))) {
seedWordInput.text = filteredList.get(0).seedWord;
seedWordInput.input.edit.cursorPosition = seedWordInput.text.length;
seedSuggestionsList.model = 0;
root.doneInsertingWord(seedWordInput.text);
}
} else {
seedSuggestionsList.model = 0;
}
}
onKeyPressed: {
root.keyPressed(event);
}
onEditClicked: {
root.editClicked();
}
}
Item {
id: suggListContainer
width: seedSuggestionsList.width
height: (((seedSuggestionsList.count <= 5) ? seedSuggestionsList.count : 5) *34) + 16
anchors.left: parent.left
anchors.leftMargin: 16
anchors.top: seedWordInput.bottom
anchors.topMargin: 4
visible: ((seedSuggestionsList.count > 0) && seedWordInput.input.edit.activeFocus)
Rectangle {
id: statusPopupMenuBackgroundContent
anchors.fill: parent
color: Theme.palette.statusPopupMenu.backgroundColor
radius: 8
layer.enabled: true
layer.effect: DropShadow {
anchors.fill: parent
source: statusPopupMenuBackgroundContent
horizontalOffset: 0
verticalOffset: 4
radius: 12
samples: 25
spread: 0.2
color: Theme.palette.dropShadow
}
}
ListView {
id: seedSuggestionsList
width: ((seedSuggestionsList.contentItem.childrenRect.width + 24) > root.width) ? root.width
: (seedSuggestionsList.contentItem.childrenRect.width + 24)
anchors.top: parent.top
anchors.topMargin: 8
anchors.bottom: parent.bottom
anchors.bottomMargin: 8
clip: true
ScrollBar.vertical: ScrollBar { }
delegate: Item {
id: txtDelegate
width: suggWord.contentWidth
height: 34
Rectangle {
width: seedSuggestionsList.width
height: parent.height
color: mouseArea.containsMouse? Theme.palette.primaryColor1 : "transparent"
}
StatusBaseText {
id: suggWord
anchors.left: parent.left
anchors.leftMargin: 14
anchors.verticalCenter: parent.verticalCenter
text: seedWord
color: mouseArea.containsMouse ? Theme.palette.indirectColor1 : Theme.palette.directColor1
font.pixelSize: 13
elide: Text.ElideRight
}
MouseArea {
id: mouseArea
width: seedSuggestionsList.width
height: parent.height
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onClicked: {
seedWordInput.text = seedWord;
seedWordInput.input.edit.cursorPosition = seedWordInput.text.length;
root.doneInsertingWord(seedWordInput.text);
seedSuggestionsList.model = 0;
}
}
}
}
}
}
@@ -1,170 +0,0 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
/*!
\qmltype StatusTokenInlineSelector
\inherits RowLayout
\inqmlmodule StatusQ.Controls
\since StatusQ.Controls 0.1
\brief It presents selectable tokens in inline form.
The \c StatusTokenInlineSelector is a graphical component that is meant to be used as inline text input.
Example of how the component looks like:
\image status_token_inline_selector.png
*/
RowLayout {
id: root
/*!
\qmlproperty var StatusTokenInlineSelector::tokens
This is a REQUIRED property that contains an array of objects that describes each token.
\qml
tokens: [{amount: 0.1, token: "ETH"}, {amount: 10, token: "SNT"}]
\endqml
*/
property var tokens
/*!
\qmlproperty var StatusTokenInlineSelector::tokenImageSourceGetter
This is a property function used to acquire image source for given token.
*/
property var tokenImageSourceGetter: function (token) {
return "../../assets/img/icons/%1.png".arg(token)
}
signal triggered(real amount, string token)
StatusBaseText {
text: qsTr("Hold")
color: Theme.palette.directColor6
font.pixelSize: 15
}
Repeater {
model: Math.max(0, root.tokens.length - 1)
delegate: Loader {
sourceComponent: tokenComponent
onLoaded: d.assignItemProperties(item, index, root.tokens[index])
}
}
StatusBaseText {
text: qsTr("or")
color: Theme.palette.directColor6
font.pixelSize: 15
}
Loader {
active: root.tokens.length > 1
sourceComponent: tokenComponent
onLoaded: {
const index = root.tokens.length - 1
d.assignItemProperties(item, index, root.tokens[index])
}
}
StatusBaseText {
text: qsTr("to post")
color: Theme.palette.directColor6
font.pixelSize: 15
}
QtObject {
id: d
function assignItemProperties(item, index, modelData) {
item.tokenImageSource = root.tokenImageSourceGetter(modelData.token)
item.token = modelData.token
item.amount = modelData.amount
item.backgroundColor = Qt.binding(() => index % 2 ? Theme.palette.primaryColor3 : Theme.palette.dangerColor3)
item.hoverColor = Qt.binding(() => index % 2 ? Theme.palette.primaryColor2 : Theme.palette.dangerColor2)
item.textColor = Qt.binding(() => index % 2 ? Theme.palette.primaryColor1 : Theme.palette.dangerColor1)
}
}
Component {
id: tokenComponent
Rectangle {
property string amount
property string token
property string tokenImageSource
property color backgroundColor
property color hoverColor
property color textColor
width: content.width + 4
height: content.height + 4
radius: height/2
color: mouseArea.containsMouse ? hoverColor : backgroundColor
Behavior on color {
ColorAnimation {
}
}
RowLayout {
id: content
anchors.centerIn: parent
StatusRoundedImage {
id: roundedImage
Layout.maximumHeight: text.height + 2
Layout.maximumWidth: text.height + 2
image.source: tokenImageSource
}
StatusBaseText {
id: text
text: amount + " " + token
color: textColor
font.pixelSize: 15
}
Item {
implicitWidth: 2
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
propagateComposedEvents: true
}
Rectangle {
id: pressIndicator
height: parent.height
radius: height / 2
color: textColor
opacity: 0.1
NumberAnimation on width {
from: 0
to: parent.width
duration: 800
running: mouseArea.containsPress
onStopped: {
if (pressIndicator.width == parent.width) {
root.triggered(amount, token)
}
pressIndicator.width = 0
}
}
}
}
}
}
@@ -1,57 +0,0 @@
import QtQuick 2.14
import StatusQ.Controls 0.1
/*!
\qmltype StatusFloatValidator
\inherits StatusValidator
\inqmlmodule StatusQ.Controls.Validators
\since StatusQ.Controls.Validators 0.1
\brief The StatusFloatValidator.qml type provides a validator for float values.
The \c StatusFloatValidator type provides a validator for float values.
Example of how to use it:
\qml
StatusFloatValidator {
bottom: 0
top: 1.25
errorMessage: qsTr("This is an invalid numeric value")
}
\endqml
For a list of components available see StatusQ.
*/
StatusValidator {
id: root
/*!
\qmlproperty string StatusFloatValidator::bottom
This property holds the validator's lowest acceptable value. By default, this property's value is derived from the lowest signed float available (typically -2147483647).
*/
property real bottom
/*!
\qmlproperty string StatusFloatValidator::locale
This property holds the name of the locale used to interpret the number.
*/
property string locale
/*!
\qmlproperty string StatusFloatValidator::top
This property holds the validator's highest acceptable value. By default, this property's value is derived from the highest float available (typically 2147483647).
*/
property real top
name: "floatValidator"
errorMessage: "Please enter a valid numeric value."
validate: function (t) {
return !isNaN(t) && t > bottom && t <= top ? true : {
bottom: bottom,
top: top,
actual: t
}
}
}
@@ -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: `Must match regex(${validatorObj.regularExpression.toString()})`
validatorObj: RegularExpressionValidator { regularExpression: root.regularExpression }
validate: function (value) {
// Basic validation management
return root.validatorObj.regularExpression.test(value)
}
}
@@ -6,7 +6,6 @@ QtObject {
property string name: ""
property string errorMessage: "invalid input"
property var validatorObj
property var validate: function (value) {
return true
-3
View File
@@ -4,10 +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
StatusFloatValidator 0.1 StatusFloatValidator.qml
-5
View File
@@ -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,14 +24,10 @@ 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
StatusSwitchTabBar 0.1 StatusSwitchTabBar.qml
StatusSelectableText 0.1 StatusSelectableText.qml
StatusTokenInlineSelector 0.1 StatusTokenInlineSelector.qml
StatusWalletColorButton 0.1 StatusWalletColorButton.qml
StatusWalletColorSelect 0.1 StatusWalletColorSelect.qml
StatusColorSelectorGrid 0.1 StatusColorSelectorGrid.qml
StatusSeedPhraseInput 0.1 StatusSeedPhraseInput.qml
-24
View File
@@ -1,30 +1,6 @@
import QtQuick 2.13
import StatusQ.Core.Theme 0.1
/*!
\qmltype StatusBaseText
\inherits Text
\inqmlmodule StatusQ.Core
\since StatusQ.Core 0.1
\brief Displays multiple lines of text. Inherits \l{https://doc.qt.io/qt-5/qml-qtquick-text.html}{Text}.
The \c StatusBaseText item displays text.
For example:
\qml
StatusBaseText {
width: 240
text: "Hello World!"
font.pixelSize: 24
color: Theme.pallete.directColor1
}
\endqml
\image status_base_text.png
For a list of components available see StatusQ.
*/
Text {
font.family: Theme.palette.baseFont.name
}
-4
View File
@@ -8,14 +8,10 @@ QtObject {
property real width
property real height
property color color
property color textColor: Qt.rgba(255, 255, 255, 0.7)
property color disabledColor
property url source
property int rotation
property bool isLetterIdenticon
property int letterSize
property int charactersLen: 1
property string emoji
property string emojiSize
property StatusIconBackgroundSettings background: StatusIconBackgroundSettings {}
}
@@ -1,66 +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 {
initalAngleRad: 0
ringPxSize: 1.5
ringSpecModel: [ {colorId: 0; segmentLength: 1},
{colorId: 5; segmentLength: 1},
{colorId: 1; segmentLength: 1},
{colorId: 1; segmentLength: 4},
{colorId: 2; segmentLength: 3} ]
distinctiveColors: ["#000000", "#726F6F", "#C4C4C4",
"#E7E7E7", "#FFFFFF", "#00FF00" ]
}
\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 or array of objects that describes each ring segment color and length.
Examples:
\qml
ringSpecModel: ListModel {ListElement{colorId: 0; segmentLength: 1} ListElement{colorId: 1; segmentLength: 2}}
\endqml
\qml
ringSpecModel: [{colorId: 0, segmentLength: 1}, {colorId: 1, segmentLength: 2}]
\endqml
*/
property var 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::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
-2
View File
@@ -92,8 +92,6 @@ QtObject {
property var accountColors: []
property var identiconRingColors: []
property QtObject statusAppLayout: QtObject {
property color backgroundColor
property color rightPanelBackgroundColor
-120
View File
@@ -1,120 +0,0 @@
pragma Singleton
import QtQuick 2.13
//import shared.status 1.0
import "../../../assets/twemoji/twemoji.js" as Twemoji
import "./emojiList.js" as EmojiJSON
QtObject {
readonly property var size: {
"veryBig": "86x86",
"big": "72x72",
"middle": "32x32",
"small": "18x18",
"verySmall": "16x16"
}
property string base: Qt.resolvedUrl("../../../assets/twemoji/")
function parse(text, renderSize = size.small) {
const renderSizes = renderSize.split("x");
if (!renderSize.includes("x") || renderSizes.length !== 2) {
throw new Error("Invalid value for 'renderSize' parameter: ", renderSize);
}
Twemoji.twemoji.base = base
Twemoji.twemoji.ext = ".svg"
Twemoji.twemoji.size = "svg"
return Twemoji.twemoji.parse(text, {
attributes: function() {
return {
width: renderSizes[0],
height: renderSizes[1],
style: "vertical-align: top"
}
}
})
}
function fromCodePoint(value) {
return Twemoji.twemoji.convert.fromCodePoint(value)
}
function deparse(value) {
// /StatusQ/src/assets/twemoji/
return value.replace(/<img src=\"qrc:\/StatusQ\/src\/assets\/twemoji\/.+?" alt=\"(.+?)\" width=\"[0-9]*\" height=\"[0-9]*\" style=\"(.+?)\" ?\/>/g, "$1");
}
function deparseFromParse(value) {
return value.replace(/<img class=\"emoji\" draggable=\"false\" alt=\"(.+?)\" src=\"qrc:\/StatusQ\/src\/assets\/twemoji\/.+?" width=\"[0-9]*\" height=\"[0-9]*\" style=\"(.+?)\" ?\/>/g, "$1");
}
function hasEmoji(value) {
let match = value.match(/<img src=\"qrc:\/StatusQ\/src\/assets\/twemoji\/.+?" alt=\"(.+?)\" width=\"[0-9]*\" height=\"[0-9]*\" style=\"(.+?)\" ?\/>/g)
return match && match.length > 0
}
function nbEmojis(value) {
let match = value.match(/<img src=\"qrc:\/StatusQ\/src\/assets\/twemoji\/.+?" alt=\"(.+?)\" width=\"[0-9]*\" height=\"[0-9]*\" style=\"(.+?)\" ?\/>/g)
return match ? match.length : 0
}
function getEmojis(value) {
return value.match(/<img class=\"emoji\" draggable=\"false\" alt=\"(.+?)\" src=\"qrc:\/StatusQ\/src\/assets\/twemoji\/.+?" width=\"[0-9]*\" height=\"[0-9]*\" style=\"(.+?)\" ?\/>/g, "$1");
}
function getEmojiUnicode(shortname) {
var _emoji;
EmojiJSON.emoji_json.forEach(function(emoji) {
if (emoji.shortname === shortname)
_emoji = emoji;
})
if (_emoji !== undefined)
return _emoji.unicode;
return undefined;
}
function getEmojiCodepoint(iconCodePoint) {
// Split the codepoint to get all the parts and then encode them from hex to utf8
const splitCodePoint = iconCodePoint.split('-')
let codePointParts = []
splitCodePoint.forEach(function (codePoint) {
codePointParts.push(`0x${codePoint}`)
})
return String.fromCodePoint(...codePointParts);
}
function getShortcodeFromId(emojiId) {
switch (emojiId) {
case 1: return ":heart:"
case 2: return ":thumbsup:"
case 3: return ":thumbsdown:"
case 4: return ":laughing:"
case 5: return ":cry:"
case 6: return ":angry:"
default: return undefined
}
}
function getEmojiFromId(emojiId) {
let shortcode = Emoji.getShortcodeFromId(emojiId)
let emojiUnicode = Emoji.getEmojiUnicode(shortcode)
if (emojiUnicode) {
return Emoji.fromCodePoint(emojiUnicode)
}
return undefined
}
function getRandomEmoji() {
var randomEmoji = EmojiJSON.emoji_json[Math.floor(Math.random() * EmojiJSON.emoji_json.length)]
const extenstionIndex = randomEmoji.unicode.lastIndexOf('.');
let iconCodePoint = randomEmoji.unicode
if (extenstionIndex > -1) {
iconCodePoint = iconCodePoint.substring(0, extenstionIndex)
}
// Split the unicode to get all the parts and then encode them from hex to utf8
const splitCodePoint = iconCodePoint.split('-')
let codePointParts = []
splitCodePoint.forEach(function (codePoint) {
codePointParts.push(`0x${codePoint}`)
})
const encodedIcon = String.fromCodePoint(...codePointParts);
return Emoji.parse(encodedIcon) + ' '
}
}
-4
View File
@@ -70,10 +70,6 @@ QtObject {
}
return strNumber.replace(/(\.[0-9]*[1-9])0+$|\.0*$/,'$1')
}
function isHtml(text) {
return (/<\/?[a-z][\s\S]*>/i.test(text))
}
}
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -1,5 +1,4 @@
module StatusQ.Core.Utils
EmojiJSON 1.0 emojiList.js
singleton Utils 0.1 Utils.qml
singleton Emoji 0.1 Emoji.qml
-1
View File
@@ -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
+2 -183
View File
@@ -5,186 +5,19 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import "statusModal" as Spares
/*!
\qmltype StatusModal
\inherits Popup
\inqmlmodule StatusQ.Popups
\since StatusQ.Popups 0.1
\brief The StatusModal provides a template for creating Modals.
Example of how to use it:
\qml
StatusModal {
anchors.centerIn: parent
header.title: "Some Title"
header.subTitle: "Subtitle"
headerActionButton: StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
width: 32
height: 32
icon.width: 20
icon.height: 20
icon.name: "info"
}
leftButtons: [
StatusRoundButton {
icon.name: "arrow-right"
rotation: 180
}
]
rightButtons: [
StatusButton {
text: "Button"
},
StatusButton {
text: "Button"
}
]
}
\endqml
For a list of components available see StatusQ.
*/
QC.Popup {
id: statusModal
/*!
\qmlproperty advancedHeader
This property represents the item loaded in header loader.
Can be used to read values from the component assigned to the loader.
\endqml
*/
property alias advancedHeader: advancedHeader.item
/*!
\qmlproperty advancedHeader
This property represents the item loaded in footer loader.
Can be used to read values from the component assigned to the loader.
\endqml
*/
property alias advancedFooter: advancedFooter.item
/*!
\qmlproperty advancedHeader
This property can be used to assign a Component to the advanced loader.
This was introduced to give more control to user on the Modal Header
example usage below
\qml
StatusModal {
id: advancedHeaderFooterModal
anchors.centerIn: parent
showHeader: false
showAdvancedHeader: true
advancedHeaderComponent: Rectangle {
width: parent.width
height: 50
color: Theme.palette.baseColor1
border.width: 1
StatusBaseText {
anchors.centerIn: parent
text: "Add any header here"
font.pixelSize: 15
color: Theme.palette.directColor1
}
}
\endqml
*/
property alias advancedHeaderComponent: advancedHeader.sourceComponent
/*!
\qmlproperty advancedHeader
This property can be used to assign a Component to the advanced loader.
This was introduced to give more control to user on the Modal Footer.
example usage below
\qml
StatusModal {
id: advancedHeaderFooterModal
anchors.centerIn: parent
showFooter: false
showAdvancedFooter: true
advancedFooterComponent: Rectangle {
width: parent.width
height: 50
color: Theme.palette.baseColor1
border.width: 1
StatusBaseText {
anchors.centerIn: parent
text: "Add any footer here"
font.pixelSize: 15
color: Theme.palette.directColor1
}
}
\endqml
*/
property alias advancedFooterComponent: advancedFooter.sourceComponent
/*!
\qmlproperty headerActionButton
This property lets the user add a button to the header of the Modal.
This does not apply to the advanced header!
\endqml
*/
property alias headerActionButton: headerImpl.actionButton
/*!
\qmlproperty header
type: StatusModalHeaderSettings
This property exposes the different properties of the standard header.
\endqml
*/
property StatusModalHeaderSettings header: StatusModalHeaderSettings {}
/*!
\qmlproperty rightButtons
This property helps user assign the right buttons on the footer.
This doesn't not apply to the advanced footer!
\endqml
*/
property StatusModalHeaderSettings header: StatusModalHeaderSettings {}
property alias rightButtons: footerImpl.rightButtons
/*!
\qmlproperty rightButtons
This property helps user assign the left buttons on the footer.
This doesn't not apply to the advanced footer!
\endqml
*/
property alias leftButtons: footerImpl.leftButtons
/*!
\qmlproperty showHeader
This property to decides whether the standard header is shown.
default value is true
\endqml
*/
property bool showHeader: true
/*!
\qmlproperty showHeader
This property to decides whether the standard footer is shown.
default value is true
\endqml
*/
property bool showFooter: true
/*!
\qmlproperty showAdvancedHeader
This property to decides whether the advanced header is shown.
default value is false.
\endqml
*/
property bool showAdvancedHeader: false
/*!
\qmlproperty showAdvancedFooter
This property decides whether the advanced footer is shown.
default value is false.
\endqml
*/
property bool showAdvancedFooter: false
/*!
\qmlproperty hasCloseButton
This property decides whether the standard header has a close button.s
\endqml
*/
property alias hasCloseButton: headerImpl.hasCloseButton
signal editButtonClicked()
@@ -231,25 +64,11 @@ QC.Popup {
onClose: statusModal.close()
}
Loader {
id: advancedHeader
anchors.top: parent.top
width: visible ? parent.width : 0
active: showAdvancedHeader
}
Spares.StatusModalFooter {
id: footerImpl
anchors.bottom: parent.bottom
width: visible ? parent.width : 0
showFooter: statusModal.showFooter
}
Loader {
id: advancedFooter
anchors.bottom: parent.bottom
width: visible ? parent.width : 0
active: showAdvancedFooter
}
}
}
+2
View File
@@ -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);
}
}
}
+4 -15
View File
@@ -20,13 +20,10 @@ StatusModal {
property string searchText: contentItem.searchText
property string noResultsLabel: "No results"
property string defaultSearchLocationText: "Anywhere"
property bool loading: false
property bool loading
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)
@@ -55,7 +52,7 @@ StatusModal {
}
function forceActiveFocus() {
contentItem.searchInput.edit.forceActiveFocus()
contentItem.searchInput.forceActiveFocus()
}
onOpened: {
@@ -85,8 +82,7 @@ StatusModal {
icon: "search"
color: Theme.palette.baseColor1
}
StatusBaseInput {
TextEdit {
id: inputText
anchors.left: statusIcon.right
anchors.leftMargin: 15
@@ -95,10 +91,6 @@ StatusModal {
anchors.verticalCenter: parent.verticalCenter
focus: true
font.pixelSize: 28
topPadding: 5 //smaller padding to handle bigger font
bottomPadding: 5
clearable: true
showBackground: false
font.family: Theme.palette.baseFont.name
color: Theme.palette.directColor1
Keys.onPressed: {
@@ -283,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"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

-3
View File
@@ -1,3 +0,0 @@
<svg width="12" height="10" viewBox="0 0 12 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.0203 1.35355C5.21556 1.15829 5.21556 0.841709 5.0203 0.646447C4.82504 0.451184 4.50846 0.451184 4.31319 0.646447L0.313195 4.64645C0.117933 4.84171 0.117933 5.15829 0.313195 5.35355L4.31319 9.35355C4.50846 9.54882 4.82504 9.54882 5.0203 9.35355C5.21556 9.15829 5.21556 8.84171 5.0203 8.64645L2.44289 6.06904C2.2329 5.85905 2.38162 5.5 2.67859 5.5H11.3334C11.6096 5.5 11.8334 5.27614 11.8334 5C11.8334 4.72386 11.6096 4.5 11.3334 4.5H2.67859C2.38162 4.5 2.2329 4.14095 2.44289 3.93096L5.0203 1.35355Z" fill="#4360DF"/>
</svg>

Before

Width:  |  Height:  |  Size: 632 B

-3
View File
@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M16.187 3.24584C17.4482 1.98472 19.4928 1.98472 20.754 3.24585C22.0151 4.50697 22.0151 6.55165 20.754 7.81277L9.00225 19.5645C8.57507 19.9917 8.04607 20.3029 7.46519 20.4689L3.25755 21.6711C2.99519 21.746 2.71282 21.6729 2.51988 21.4799C2.32694 21.287 2.25377 21.0046 2.32873 20.7423L3.53092 16.5346C3.69688 15.9537 4.00815 15.4247 4.43533 14.9975L16.187 3.24584ZM19.6914 4.30837C19.0171 3.63407 17.9239 3.63407 17.2496 4.30837L5.49785 16.0601C5.25124 16.3067 5.07155 16.6121 4.97574 16.9474C4.61369 18.2146 5.78522 19.3861 7.05238 19.0241C7.38772 18.9283 7.69311 18.7486 7.93972 18.5019L19.6914 6.75024C20.3657 6.07594 20.3657 4.98268 19.6914 4.30837Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 820 B

-3
View File
@@ -1,3 +0,0 @@
<svg width="18" height="20" viewBox="0 0 18 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.8536 1.1484C16.6583 1.34366 16.3417 1.34366 16.1464 1.1484L15.3536 0.355507C15.1583 0.160245 14.8417 0.160244 14.6464 0.355506L13.8536 1.1484C13.6583 1.34366 13.3417 1.34366 13.1464 1.1484L12.3536 0.355507C12.1583 0.160245 11.8417 0.160244 11.6464 0.355506L10.8536 1.1484C10.6583 1.34366 10.3417 1.34366 10.1464 1.1484L9.35355 0.355507C9.15829 0.160245 8.84171 0.160244 8.64645 0.355506L7.85355 1.1484C7.65829 1.34366 7.34171 1.34366 7.14645 1.1484L6.35355 0.355507C6.15829 0.160245 5.84171 0.160244 5.64645 0.355506L4.85355 1.1484C4.65829 1.34366 4.34171 1.34366 4.14645 1.1484L3.35355 0.355507C3.15829 0.160245 2.84171 0.160244 2.64645 0.355506L1.85355 1.1484C1.65829 1.34366 1.34171 1.34366 1.14645 1.1484L0.853554 0.855507C0.538571 0.540525 0 0.763608 0 1.20906V18.7948C0 19.2403 0.538571 19.4634 0.853553 19.1484L1.14645 18.8555C1.34171 18.6602 1.65829 18.6602 1.85355 18.8555L2.64645 19.6484C2.84171 19.8437 3.15829 19.8437 3.35355 19.6484L4.14645 18.8555C4.34171 18.6602 4.65829 18.6602 4.85355 18.8555L5.64645 19.6484C5.84171 19.8437 6.15829 19.8437 6.35355 19.6484L7.14645 18.8555C7.34171 18.6602 7.65829 18.6602 7.85355 18.8555L8.64645 19.6484C8.84171 19.8437 9.15829 19.8437 9.35355 19.6484L10.1464 18.8555C10.3417 18.6602 10.6583 18.6602 10.8536 18.8555L11.6464 19.6484C11.8417 19.8437 12.1583 19.8437 12.3536 19.6484L13.1464 18.8555C13.3417 18.6602 13.6583 18.6602 13.8536 18.8555L14.6464 19.6484C14.8417 19.8437 15.1583 19.8437 15.3536 19.6484L16.1464 18.8555C16.3417 18.6602 16.6583 18.6602 16.8536 18.8555L17.1464 19.1484C17.4614 19.4634 18 19.2403 18 18.7948V1.20906C18 0.763608 17.4614 0.540524 17.1464 0.855507L16.8536 1.1484ZM16 16.592C16 16.8681 15.7761 17.092 15.5 17.092H2.5C2.22386 17.092 2 16.8681 2 16.592V3.41195C2 3.13581 2.22386 2.91195 2.5 2.91195H15.5C15.7761 2.91195 16 3.13581 16 3.41195V16.592ZM3 13.502C3 13.2258 3.22386 13.002 3.5 13.002H14.5C14.7761 13.002 15 13.2258 15 13.502V14.502C15 14.7781 14.7761 15.002 14.5 15.002H3.5C3.22386 15.002 3 14.7781 3 14.502V13.502ZM3 9.50195C3 9.22581 3.22386 9.00195 3.5 9.00195H14.5C14.7761 9.00195 15 9.22581 15 9.50195V10.502C15 10.7781 14.7761 11.002 14.5 11.002H3.5C3.22386 11.002 3 10.7781 3 10.502V9.50195ZM3 5.50195C3 5.22581 3.22386 5.00195 3.5 5.00195H14.5C14.7761 5.00195 15 5.22581 15 5.50195V6.50195C15 6.7781 14.7761 7.00195 14.5 7.00195H3.5C3.22386 7.00195 3 6.7781 3 6.50195V5.50195Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 934 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 788 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Some files were not shown because too many files have changed in this diff Show More