Compare commits

..
57 Commits
Author SHA1 Message Date
Alexandra Betouni f9f054e3d6 feat(StatusSeedPhraseInput): exposed touch/keys pressed events
Exposed keys.onPressed signal, mouse on clicked signal
as well as tabNavItem to be set in KeyNavigation.tab
when needed

Needed for task https://github.com/status-im/status-desktop/issues/4955
2022-03-30 01:23:06 +03:00
Noelia 684f45cc08 fix(StatusChatListCategory): Selecting the category menu should not toggle the category itself
Closes `status-desktop` issue https://github.com/status-im/status-desktop/issues/4914
2022-03-29 11:50:29 +02:00
Stefan eae4e0f405 tests(StatusInput): add regression test to check for qml output
Also improves on the test structure
2022-03-28 22:52:36 +03:00
Michał Iskierko b2ac2794bb fix(StatusSearchPopup): Fix cutting text with big font (#604)
Decreasing padding.
Setting loading property default to false.

Fix #5197
2022-03-28 13:14:15 -04:00
Patryk Osmaczko b565a32c7e fix(StatusInput): add implicitHeight
It makes it work with layouts correctly.
2022-03-28 15:27:13 +02:00
Patryk Osmaczko a1835164d9 fix(StatusBaseInput): fix default padding when leftComponent is loaded 2022-03-28 15:26:39 +02:00
Alexandra Betouni 06e931d749 fix(StatusSeedPhraseInput): Increased suggestion match chars to 4 2022-03-26 07:46:11 +01:00
Khushboo Mehta b9aa49853a fix(StatusInput): Added mising documentation of new properties to StatusInput and StatusModal
Moved the StatusInputWithCursor out of StatusQ as it not needed under StatusQ.
2022-03-25 14:51:53 +01:00
Khushboo Mehta 03eb6302d5 fix(StatusModal): Added support for advanced footer and header as seen in new designs.
It is also backward compatible and is not a breaking change.
2022-03-25 14:51:53 +01:00
Khushboo Mehta 5f8f798cf2 feat(StatusInput): Expose errorMessage so that its placement can be controlled from outside 2022-03-25 14:51:53 +01:00
Khushboo Mehta bbc0177a66 fix(StatusListItemTag): Fix for allignment in StatusListItemTag and option to make close button invisible 2022-03-25 14:51:53 +01:00
Khushboo Mehta 6ce9f9bd86 feat: Added new icon fees 2022-03-25 14:51:53 +01:00
Khushboo Mehta 46254f79c4 feat(StatusFloatValidator): Used to validate a float variable for
1. Is a valid number
2. Is greater than bottom value
3. Is less than top value
2022-03-25 14:51:53 +01:00
Khushboo Mehta ad659a5dc2 feat(StatusInputWithCursor): Extended the StatusInput to support an Input with no background and a blinking custom cursor 2022-03-25 14:51:53 +01:00
Alexandra Betouni 41f67b59e9 fix(StatusTagSelector): move suggestions popup inside component (#598)
Closes #531
2022-03-24 18:03:36 -04:00
r4bbit.eth aa91a88be7 chore: add check for dark and light theme to PR template (#597) 2022-03-24 07:03:31 +01:00
Boris Melnik f299c9df3a fix(StatusQ.Popups): Replace TextEdit to StatusBaseInput for SearchPopup
Closes: https://github.com/status-im/status-desktop/issues/5059
2022-03-23 17:16:52 +01:00
Patryk Osmaczko b6c3231e30 feat(StatusQ.Controls): add StatusTokenInlineSelector
Closes: status-im/status-desktop#4937
2022-03-23 11:00:57 +01:00
Jonathan Rainville 496ad05247 fix(StatusLetterIdenticon): fix emoji positioning
The emoji wasn't centered correctly on Windows
Fixes #5045
2022-03-23 07:29:34 +01:00
Patryk Osmaczko 93f9214aad fix(StatusBaseInput): apply changes required by StatusSeedPhraseInput 2022-03-22 19:45:52 +01:00
Patryk Osmaczko 22bbf9b177 refactor(StatusBaseInput): use RowLayout for position management 2022-03-22 19:45:52 +01:00
Noelia 7301323ed7 fix(StatusPasswordStrengthIndicator): Added new onValueChanged condition
Added new `onValueChanged` condition if bar value is 0 --> Strength.None.
2022-03-22 10:21:48 +01:00
Alexandra Betouni c6e4cf627c fix(SeedPhraseInput): Fixing SeedPhraseInput control height
The suggestion list should be showing up to 5 seed
word entries
2022-03-22 09:20:13 +01:00
Alexandra Betouni 5c1c9852ae fix(SeedPhraseInput): fix lost focus after typing one character
Relates to: https://github.com/status-im/status-desktop/issues/4955
2022-03-22 09:17:18 +01:00
osmaczko be2b2c3df7 ci: add pull request template 2022-03-21 14:19:57 +01:00
Jonathan Rainville 1362a94448 fix(StatusChatListItem): add missing import (#585) 2022-03-18 12:15:38 -04:00
Jonathan Rainville 189f66225c fix(StatusIconSettings): set charactersLen to 1 by default (#581)
This caused a breaking change where components that used to imply 1 charactersLen now showed no character at all because it defaulted to 0.
2022-03-17 15:08:51 -04:00
Jonathan Rainville 40d8b9c2f6 feat(StatusIconSetting): add emojiSize setting for icons (#579) 2022-03-17 14:14:39 -04:00
Jonathan Rainville 8af7028efc fix(StatusContactRequestIndicatorListItem): hide badge when value is 0 (#580)
* fix(StatusContactRequestIndicatorListItem): hide badge when value is 0

* feat(icons): add edit pencil icon
2022-03-17 11:56:44 -04:00
Alexandra Betouni f1eff6700a feat(StatusQ/Controls): Adding StatusSeedPhraseInput control
Also added an example in Inputs page

Closes #567
2022-03-17 11:24:36 +01:00
Stefan 082bb8ef45 docs(StatusInput): Initial basic docs plus validationMode 2022-03-14 02:43:01 -07:00
Stefan 7609450068 test(StatusInput): Add initial basic tests 2022-03-14 02:43:01 -07:00
Stefan 6570275176 fix(dev): silence qml warnings 2022-03-14 02:43:01 -07:00
Stefan 4b579cddbe feat(StatusInput): add mode to ingnore unvalidated content
Add optional feature to StatusInput not to allow typing characters
that are not validated

updates #4961
2022-03-14 02:43:01 -07:00
osmaczko a84026d74d Add various of changes required by emojiHash and identiconRing integration (#577)
* chore(StatusIdenticonRing): make ringSpecModel accept array of objects

* chore(StatusLetterIdenticon): add charactersLen and textColor settings
2022-03-13 09:00:55 -04:00
Khushboo-dev-cpp 428b165198 feat: Add emoji support (#575)
* feat: Add emoji support
1. StatusChatListItem (only updated parts already done by Jo)
2. StatusListItem
3. StatusInput

* feat(StatusColorSelectorGrid): Added new widget for color selection as needed in wallet

* fix(StatusInput): on reset, valid should be set to true else error mode is shown even though the user hasnt entered a value

* fix(StatusLetterIdenticon): Removed the clicked event out from the LetterIdenticon and added it to the StatusBaseInput as other places that use the letterIdenticon dont need the mouse area is not needed
2022-03-11 14:34:21 -05:00
Jonathan Rainville 56b2663e4d fix(StatusQ.Validators): fix regular expression test in validator 2022-03-10 17:10:15 +01:00
Anthony Laibe 9dbb7ec53f fix(@StatusListItem): Use tags model 2022-03-10 15:14:14 +01:00
Alexandra Betouni 7e9c7a52fd feat(StatusLetterIdenticon): Added charCount property in StatusLetterIdenticon
For desktop task #4956 the letter identicon displayed inside
the StatusSmartIdenticon should be of 2 characters and not 1.
2022-03-10 10:06:07 +01:00
Noelia 2e33fb9f81 feat(StatusPasswordStrengthIndicator): Add new Strength type None
Add new Strength type None and its corresponding state.
2022-03-09 13:17:58 +01:00
Pascal Precht 208825807b chore: cut v0.25.0 release 2022-03-07 19:11:38 +01:00
Anthony Laibe 381150a7b5 feat(@StatusListItem): add option for tags 2022-03-07 13:29:26 +01:00
Jonathan Rainville 5fac8774f4 feat(StatusChatListItem): enable assigning emoji to chat item 2022-03-07 10:19:43 +01:00
Anthony Laibe e9f20be15a feat(StatusQ.Core): add new arrow-left icon 2022-03-03 10:53:50 +01:00
Anthony Laibe 9d06aae1f4 fix(build): fix linux build
Fixes #413
2022-03-03 10:50:45 +01:00
Anthony Laibe f574e39012 fix(@StatusListItem): fix left padding
When there is an icon, take it into account when calculating the left
padding
2022-03-02 19:01:12 +01:00
Jonathan Rainville 8495fae8a5 fix(StatusListItem): add propagateTitleClicks property to StatusListItem
Makes it possible disable the propagation of the mouse event when it's not wanted, for example in the search popup, where if the user clicks the title, we want to show the profile popup, but not navigate to the channel
2022-02-23 09:49:59 +01:00
Alexandra Betouni 07a5dc09ac fix(StatusTagSelector): Updates and fixes in the component
Moved `remove` function below remove contact signal
also removed online status badge from CreateChatView

Fixed as well name tags to be adapting on parent's
width and scrolling the list to the end when this is
bigger than the available width. Switcehd to use
nameCountLimit property where needed
2022-02-22 11:27:35 +01:00
Boris Melnik 9e6fbe955a feat(StatusChatList): Highlight chat item at creation time
Part of: https://github.com/status-im/status-desktop/issues/4767
2022-02-21 08:46:20 +01:00
Noelia 1217771fd0 feat(StatusPinInput): Introduce StatusPinInput control
It creates `StatusPinInput` control that allows customzing its circle diameter, circle spacing and pin length. It contains a `TextInput` object that will provide the component, input text management like validation rules.

It incorporates a blinking animation when the control is focused and feedback (mouse shape changed) when hovering it.

It adds new page in sandbox to play with `StatusPinInput` control.

It adds component documentation.

Also it creates 2 new `StatusValidator` controls with their corresponding documentation:
- `StatusRegularExpressionValidator` which wraps a QML type `RegularExpressionValidator`.

- `StatusIntValidator` which wraps a QML type `IntValidator`.

Closes #524
2022-02-18 09:25:05 +01:00
Noelia 3b86d13a96 feat(StatusSmartIdenticon): Add support for color rings in StatusSmartIdenticon (#553)
Created new control `StatusIdenticonRing` and used in `StatusSmartIdenticon` component.

Added property assignments in sandbox models to display the `StatusIdenticonRing` when needed.

Added first documentation approach for `StatusIdenticonRing` and `StatusIdenticonRingSettings`.

Closes #517
2022-02-17 09:20:17 +01:00
Noelia c0f825c690 feat(StatusContactVerificationIcons): Create new row control that includes mutual connect and trust indicator icons (#559)
Create `StatusContactVerificationIcons` row component.

Refactor in `StatusMemberListItem`. It now uses `StatusContactVerificationIcons` component.

Refactor in `StatusListItem`. It now contains a Loader for dynamically decide if a row icons component is defined aside the title.

Refactor in `StatusMessageHeader` and `StatusMessage`. They now use `StatusContactVerificationIcons` component.

Closes #542

BREAKING CHANGES:

Removed `titleIcon1Visible` and `titleIcon1Visible` from `StatusListItem`.

Removed `ContactType` enumeration in `StatusMessage`. Now, contact verification type is managed by enum `TrustedType` in `StatusContactVerificationIcons` component.
2022-02-16 11:37:48 +01:00
Alexandra Betouni 825999b151 feat(StatusQ): Moving docs outside sandbox
To generate docs, from doc folder run
/path/to/Qt/installation/bin/qdoc statusq.qdocconf

A folder named "html" will be generated under doc,
open the statusq-index.html to get to the home page.
2022-02-15 08:43:33 +01:00
Alexandra Betouni cdf51fefbd fix(sandbox): Fix results popup component position
Fixed alignment when results are being filtered.
If the x position that the popup should be aligned
goes off the screen, the popup appears back on
position 0. Also fixed result list item was not
vertically centered.
2022-02-15 08:40:19 +01:00
Alexandra Betouni 665141f81d fix(StatusQ.Popups): removed overlay setting (#557)
A MouseArea was set as an Overlay to the PopupMenu
consuming all clicks outside the component until it
was closed. Removed it as it's not necessary anymore.

Closes https://github.com/status-im/status-desktop/issues/3599
2022-02-15 05:08:15 +02:00
Pascal Precht 9cbd19d658 chore: release v0.24.0 2022-02-14 10:02:02 +01:00
Alexandra Betouni 0e00fd24ab feat(StatusQ) Adding qdoc related files (#555)
Added qdoc conf & source files for each
StatusQ module. Documented StatusBaseText
from StatusQ.Core as an example

To generate docs, from sandbox/docs run
/path/to/Qt/installation/bin/qdoc statusq.qdocconf

A folder named "html" will be generated under sandbox/doc,
open the statusq-index.html to get to the home page.

Closes #550
2022-02-11 09:55:44 -05:00
10185 changed files with 23907 additions and 1993 deletions
+17
View File
@@ -0,0 +1,17 @@
### 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,3 +13,7 @@ Makefile
*_qml.cpp
*_qmlcache.qrc
sandbox/qmlcache_loader.cpp
doc/html
CMakeLists.txt.user
.vscode
build/
+40
View File
@@ -1,3 +1,43 @@
<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)

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

@@ -30,8 +30,10 @@
\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}
@@ -39,5 +41,7 @@
\li \l{StatusSelectableText}
\li \l{StatusWalletColorButton}
\li \l{StatusWalletColorSelect}
\li \l{StatusRegularExpressionValidator}
\li \l{StatusIntValidator}
\endlist
*/
@@ -15,6 +15,7 @@
\li \l{StatusIcon}
\li \l{StatusIconBackgroundSettings}
\li \l{StatusIconSettings}
\li \l{StatusIdenticonRingSettings}
\li \l{StatusImageSettings}
\li \l{StatusModalHeaderSettings}
\li \l{StatusTooltipSettings}
@@ -5,16 +5,16 @@ url = https://github.com/status-im/StatusQ
#These are set implictly by qdoc as well, but only with these the module header can be found
includepaths = -I . \
-I $PWD/../../src/StatusQ
-I $PWD/../src/StatusQ
imagedirs = src/images
sourcedirs += src \
$PWD/../../src/StatusQ/Components \
$PWD/../../src/StatusQ/Controls \
$PWD/../../src/StatusQ/Core \
$PWD/../../src/StatusQ/Layout \
$PWD/../../src/StatusQ/Platform \
$PWD/../../src/StatusQ/Popups \
$PWD/../src/StatusQ/Components \
$PWD/../src/StatusQ/Controls \
$PWD/../src/StatusQ/Core \
$PWD/../src/StatusQ/Layout \
$PWD/../src/StatusQ/Platform \
$PWD/../src/StatusQ/Popups \
sources.fileextensions = "*.cpp *.qdoc *.qml"
@@ -1,15 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- StatusBaseText.qml -->
<title>List of All Members for StatusBaseText | StatusQ 0.1</title>
<link rel="stylesheet" type="text/css" href="style/style.css"/>
</head>
<body>
<p class="header"><small>StatusQ - A Components selection for Status dekstop client. </p></small></p><hr/><li><a href="statusq-index.html">StatusQ</a></li>
<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">List of All Members for StatusBaseText</h1>
<p>This is the complete list of members for <a href="qml-statusq-core-statusbasetext.html">StatusBaseText</a>, including inherited members.</p>
<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></body>
</html>
-41
View File
@@ -1,41 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- StatusBaseText.qml -->
<title>StatusBaseText QML Type | StatusQ 0.1</title>
<link rel="stylesheet" type="text/css" href="style/style.css"/>
</head>
<body>
<p class="header"><small>StatusQ - A Components selection for Status dekstop client. </p></small></p><hr/><li><a href="statusq-index.html">StatusQ</a></li>
<div class="sidebar">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#details">Detailed Description</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">StatusBaseText QML Type</h1>
<span class="subtitle"></span>
<!-- $$$StatusBaseText-brief -->
<p>Displays multiple lines of text. Inherits <a href="https://doc.qt.io/qt-5/qml-qtquick-text.html">Text</a>. <a href="#details">More...</a></p>
<!-- @@@StatusBaseText -->
<div class="table"><table class="alignedsummary">
<tr><td class="memItemLeft rightAlign topAlign"> Import Statement:</td><td class="memItemRight bottomAlign"> import StatusQ.Core 0.1</td></tr><tr><td class="memItemLeft rightAlign topAlign"> Since:</td><td class="memItemRight bottomAlign"> StatusQ.Core 0.1</td></tr></table></div><ul>
<li><a href="qml-statusq-core-statusbasetext-members.html">List of all members, including inherited members</a></li>
</ul>
<!-- $$$StatusBaseText-description -->
<a name="details"></a>
<h2 id="details">Detailed Description</h2>
<p>The <code>StatusBaseText</code> item displays text. For example:</p>
<pre class="qml"><span class="type"><a href="qml-statusq-core-statusbasetext.html">StatusBaseText</a></span> {
<span class="name">width</span>: <span class="number">240</span>
<span class="name">text</span>: <span class="string">&quot;Hello World!&quot;</span>
<span class="name">font</span>.pixelSize: <span class="number">24</span>
<span class="name">color</span>: <span class="name">Theme</span>.<span class="name">pallete</span>.<span class="name">directColor1</span>
}</pre>
<p class="centerAlign"><img src="images/status_base_text.png" alt="" /></p><p>For a list of components available see <a href="statusq-index.html">StatusQ</a>.</p>
<!-- @@@StatusBaseText -->
<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></body>
</html>
-53
View File
@@ -1,53 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- statusqcomponents.qdoc -->
<title>StatusQ Components | StatusQ 0.1</title>
<link rel="stylesheet" type="text/css" href="style/style.css"/>
</head>
<body>
<p class="header"><small>StatusQ - A Components selection for Status dekstop client. </p></small></p><hr/><li><a href="statusq-index.html">StatusQ</a></li>
<li>StatusQ Components</li>
<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">StatusQ Components</h1>
<span class="subtitle"></span>
<!-- $$$StatusQ.Components-description -->
<div class="descr"> <a name="details"></a>
<p>This is a listing of all Components components.</p>
<p>This module is part of the <a href="statusq-index.html">StatusQ</a> project.</p>
<ul>
<li>StatusAddress</li>
<li>StatusBadge</li>
<li>StatusChatInfoToolBar</li>
<li>StatusChatList</li>
<li>StatusChatListItem</li>
<li>StatusImageSettings</li>
<li>StatusChatListCategory</li>
<li>StatusChatListCategoryItem</li>
<li>StatusChatListAndCategories</li>
<li>StatusChatToolBar</li>
<li>StatusContactRequestsIndicatorListItem</li>
<li>StatusDescriptionListItem</li>
<li>StatusLetterIdenticon</li>
<li>StatusListItem</li>
<li>StatusListSectionHeadline</li>
<li>StatusLoadingIndicator</li>
<li>StatusMemberListItem</li>
<li>StatusNavigationListItem</li>
<li>StatusNavigationPanelHeadline</li>
<li>StatusRoundIcon</li>
<li>StatusRoundedImage</li>
<li>StatusMacWindowButtons</li>
<li>StatusListItemBadge</li>
<li>StatusExpandableItem</li>
<li>StatusSmartIdenticon</li>
<li>StatusMessage</li>
<li>StatusMessageDetails</li>
<li>StatusTagSelector</li>
<li>StatusToastMessage</li>
</ul>
</div>
<!-- @@@StatusQ.Components -->
<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></body>
</html>
-55
View File
@@ -1,55 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- statusqcontrols.qdoc -->
<title>StatusQ Controls | StatusQ 0.1</title>
<link rel="stylesheet" type="text/css" href="style/style.css"/>
</head>
<body>
<p class="header"><small>StatusQ - A Components selection for Status dekstop client. </p></small></p><hr/><li><a href="statusq-index.html">StatusQ</a></li>
<li>StatusQ Controls</li>
<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">StatusQ Controls</h1>
<span class="subtitle"></span>
<!-- $$$StatusQ.Controls-description -->
<div class="descr"> <a name="details"></a>
<p>This is a listing of all Controls components.</p>
<p>This module is part of the <a href="statusq-index.html">StatusQ</a> project.</p>
<ul>
<li>StatusAccountSelector</li>
<li>StatusAssetSelector</li>
<li>StatusBanner</li>
<li>StatusChatCommandButton</li>
<li>StatusChatInfoButton</li>
<li>StatusChatListCategoryItemButton</li>
<li>StatusColorSelector</li>
<li>StatusIconTabButton</li>
<li>StatusNavBarTabButton</li>
<li>StatusTabBarIconButton</li>
<li>StatusToolTip</li>
<li>StatusBaseButton</li>
<li>StatusButton</li>
<li>StatusFlatButton</li>
<li>StatusRoundButton</li>
<li>StatusFlatRoundButton</li>
<li>StatusSwitch</li>
<li>StatusRadioButton</li>
<li>StatusCheckBox</li>
<li>StatusSlider</li>
<li>StatusSelect</li>
<li>StatusBaseInput</li>
<li>StatusInput</li>
<li>StatusPickerButton</li>
<li>StatusProgressBar</li>
<li>StatusPasswordStrengthIndicator</li>
<li>StatusSwitchTabButton</li>
<li>StatusSwitchTabBar</li>
<li>StatusSelectableText</li>
<li>StatusWalletColorButton</li>
<li>StatusWalletColorSelect</li>
</ul>
</div>
<!-- @@@StatusQ.Controls -->
<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></body>
</html>
-35
View File
@@ -1,35 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- statusqcore.qdoc -->
<title>StatusQ Core | StatusQ 0.1</title>
<link rel="stylesheet" type="text/css" href="style/style.css"/>
</head>
<body>
<p class="header"><small>StatusQ - A Components selection for Status dekstop client. </p></small></p><hr/><li><a href="statusq-index.html">StatusQ</a></li>
<li>StatusQ Core</li>
<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">StatusQ Core</h1>
<span class="subtitle"></span>
<!-- $$$StatusQ.Core-description -->
<div class="descr"> <a name="details"></a>
<p>This is a listing of all Core components. These files are available for general import and they are based off the <a href="https://doc.qt.io/qt-5/qtquick-qmlmodule.html">Qt Quick Primitives</a> and <a href="https://doc.qt.io/archives/qt-5.11/qtquick-controls2-qmlmodule.html">Qt Quick Controls 2</a>.</p>
<p>This module is part of the <a href="statusq-index.html">StatusQ</a> project.</p>
<ul>
<li>StatusAppNavBarFilterModel</li>
<li><a href="qml-statusq-core-statusbasetext.html">StatusBaseText</a></li>
<li>StatusIcon</li>
<li>StatusIconBackgroundSettings</li>
<li>StatusIconSettings</li>
<li>StatusImageSettings</li>
<li>StatusModalHeaderSettings</li>
<li>StatusTooltipSettings</li>
</ul>
</div>
<!-- @@@StatusQ.Core -->
<div class="table"><table class="annotated">
<tr class="odd topAlign"><td class="tblName"><p><a href="qml-statusq-core-statusbasetext.html">StatusBaseText</a></p></td><td class="tblDescr"><p>Displays multiple lines of text. Inherits Text</p></td></tr>
</table></div>
<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></body>
</html>
-28
View File
@@ -1,28 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- statusq-overview.qdoc -->
<title>StatusQ 0.1</title>
<link rel="stylesheet" type="text/css" href="style/style.css"/>
</head>
<body>
<p class="header"><small>StatusQ - A Components selection for Status dekstop client. </p></small></p><hr/><div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">StatusQ</h1>
<span class="subtitle"></span>
<!-- $$$statusq-index.html-description -->
<div class="descr"> <a name="details"></a>
<p><a href="statusq-index.html">StatusQ</a> provides a collection of components..&#x2e;&#x2e;</p>
<p><a href="statusq-index.html">StatusQ</a> - Components and Interfaces</p>
<ul>
<li><a href="statusq-components-qmlmodule.html">Components</a></li>
<li><a href="statusq-controls-qmlmodule.html">Controls</a></li>
<li><a href="statusq-core-qmlmodule.html">Core</a></li>
<li><a href="statusq-layout-qmlmodule.html">Layout</a></li>
<li><a href="statusq-platform-qmlmodule.html">Platform</a></li>
<li><a href="statusq-popups-qmlmodule.html">Popups</a></li>
</ul>
</div>
<!-- @@@statusq-index.html -->
<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></body>
</html>
-28
View File
@@ -1,28 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- statusqlayout.qdoc -->
<title>StatusQ Layout | StatusQ 0.1</title>
<link rel="stylesheet" type="text/css" href="style/style.css"/>
</head>
<body>
<p class="header"><small>StatusQ - A Components selection for Status dekstop client. </p></small></p><hr/><li><a href="statusq-index.html">StatusQ</a></li>
<li>StatusQ Layout</li>
<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">StatusQ Layout</h1>
<span class="subtitle"></span>
<!-- $$$StatusQ.Layout-description -->
<div class="descr"> <a name="details"></a>
<p>This is a listing of all Layout components.</p>
<p>This module is part of the <a href="statusq-index.html">StatusQ</a> project.</p>
<ul>
<li>StatusAppLayout</li>
<li>StatusAppNavBar</li>
<li>StatusAppTwoPanelLayout</li>
<li>StatusAppThreePanelLayout</li>
</ul>
</div>
<!-- @@@StatusQ.Layout -->
<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></body>
</html>
-27
View File
@@ -1,27 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- statusqplatform.qdoc -->
<title>StatusQ Platform | StatusQ 0.1</title>
<link rel="stylesheet" type="text/css" href="style/style.css"/>
</head>
<body>
<p class="header"><small>StatusQ - A Components selection for Status dekstop client. </p></small></p><hr/><li><a href="statusq-index.html">StatusQ</a></li>
<li>StatusQ Platform</li>
<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">StatusQ Platform</h1>
<span class="subtitle"></span>
<!-- $$$StatusQ.Platform-description -->
<div class="descr"> <a name="details"></a>
<p>This is a listing of all Platform components.</p>
<p>This module is part of the <a href="statusq-index.html">StatusQ</a> project.</p>
<ul>
<li>StatusMacTrafficLights</li>
<li>StatusMacNotification</li>
<li>StatusWindowsTitleBar</li>
</ul>
</div>
<!-- @@@StatusQ.Platform -->
<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></body>
</html>
-34
View File
@@ -1,34 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- statusqpopups.qdoc -->
<title>StatusQ Popups | StatusQ 0.1</title>
<link rel="stylesheet" type="text/css" href="style/style.css"/>
</head>
<body>
<p class="header"><small>StatusQ - A Components selection for Status dekstop client. </p></small></p><hr/><li><a href="statusq-index.html">StatusQ</a></li>
<li>StatusQ Popups</li>
<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">StatusQ Popups</h1>
<span class="subtitle"></span>
<!-- $$$StatusQ.Popups-description -->
<div class="descr"> <a name="details"></a>
<p>This is a listing of all Popups components.</p>
<p>This module is part of the <a href="statusq-index.html">StatusQ</a> project.</p>
<ul>
<li>StatusMenuSeparator</li>
<li>StatusPopupMenu</li>
<li>StatusMenuItem</li>
<li>StatusMenuItemDelegate</li>
<li>StatusModal</li>
<li>StatusSearchPopup</li>
<li>StatusModalDivider</li>
<li>StatusSearchPopupMenuItem</li>
<li>StatusSearchLocationMenu</li>
<li>StatusSpellcheckingMenuItems</li>
</ul>
</div>
<!-- @@@StatusQ.Popups -->
<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></body>
</html>
-1036
View File
File diff suppressed because it is too large Load Diff
+38 -2
View File
@@ -64,6 +64,12 @@ 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"
@@ -322,6 +328,25 @@ 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 Emoji"
subTitle: "Emoji"
icon.emoji: "😁"
icon.color: "yellow"
icon.letterSize: 14
icon.isLetterIdenticon: true
}
StatusDescriptionListItem {
title: "Title"
subTitle: "Subtitle"
@@ -351,18 +376,29 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
nickName: "This is an example"
userName: "annabelle"
chatKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
trustIndicator: StatusMemberListItem.TrustedType.Verified
trustIndicator: StatusContactVerificationIcons.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: StatusMemberListItem.TrustedType.Untrustworthy
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
}
StatusMemberListItem {
+41
View File
@@ -78,6 +78,11 @@ Column {
onClicked: editTitleModal.open()
}
StatusButton {
text: "Modal with Advanced Header/Footer"
onClicked: advancedHeaderFooterModal.open()
}
StatusModal {
id: simpleModal
anchors.centerIn: parent
@@ -353,6 +358,42 @@ 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"}
+2 -1
View File
@@ -41,7 +41,8 @@ ListView {
}
messageText: model.message
hasMention: model.hasMention
contactType: model.contactType
isMutualContact: model.isMutualContact
trustIndicator: model.trustIndicator
isPinned: model.isPinned
pinnedBy: model.pinnedBy
hasExpired: model.hasExpired
+7 -171
View File
@@ -1,8 +1,6 @@
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
@@ -28,33 +26,19 @@ Page {
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: 17
implicitHeight: 44
maxHeight: root.height
toLabelText: qsTr("To: ")
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 { }
warningText: qsTr("USER LIMIT REACHED")
listLabel: qsTr("Contacts")
onTextChanged: {
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;
}
sortModel(root.contactsModel);
}
Component.onCompleted: { sortModel(root.contactsModel); }
}
StatusButton {
implicitHeight: 44
Layout.alignment: Qt.AlignTop
enabled: (tagSelector.namesModel.count > 0)
text: "Confirm"
}
@@ -62,155 +46,7 @@ Page {
contentItem: Item {
anchors.fill: parent
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();
}
}
}
anchors.topMargin: 68
StatusBaseText {
visible: (contactsModel.count === 0)
@@ -266,6 +266,8 @@ StatusAppThreePanelLayout {
image.source: model.source
image.isIdenticon: model.isIdenticon
isOnline: model.isOnline
ringSettings.ringSpecModel: model.ringSpecModel
ringSettings.distinctiveColors: Theme.palette.identiconRingColors
}
}
}
+58 -22
View File
@@ -497,7 +497,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f5789"
contactType: 2
isMutualContact: true
trustIndicator: StatusContactVerificationIcons.TrustedType.None
hasMention: false
editMode: false
isReply: false
@@ -525,7 +526,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f2333"
contactType: 3
isMutualContact: true
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
hasMention: false
editMode: false
isReply: false
@@ -552,7 +554,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAkUlEQVR4nOzYwQmDQBQG4SSkl3SQyizDyuzAavTi0cPK8sPwM9/Rw8rw4KH7eZUwhMYQGkNoDKGpCfmmDl63/bh7vvx/78T7aiZiCI0hNMMbJL2FZs+vmYghNIbQTG+cp9smtf1qJmIIjSEKqZmIITSG0Azfa6W/qfxDvBhCY4hCaiZiCI0hNIbQGEJzBgAA///3pSBjX42sYAAAAABJRU5ErkJggg=="
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f2333"
contactType: 3
isMutualContact: true
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
hasMention: false
editMode: false
isReply: false
@@ -579,7 +582,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg="
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f6789"
contactType: 4
isMutualContact: false
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
hasMention: false
editMode: false
isReply: false
@@ -607,7 +611,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
contactType: 0
isMutualContact: true
trustIndicator: StatusContactVerificationIcons.TrustedType.None
hasMention: false
editMode: false
isReply: false
@@ -635,7 +640,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
contactType: 0
isMutualContact: false
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
hasMention: false
editMode: false
isReply: false
@@ -663,7 +669,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
contactType: 0
isMutualContact: false
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
hasMention: true
editMode: false
isReply: false
@@ -692,7 +699,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
contactType: 0
isMutualContact: false
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
hasMention: false
editMode: false
isReply: true
@@ -721,7 +729,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
contactType: 0
isMutualContact: false
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
hasMention: false
editMode: false
isReply: true
@@ -750,7 +759,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
contactType: 0
isMutualContact: false
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
hasMention: false
editMode: false
isReply: true
@@ -779,7 +789,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
contactType: 0
isMutualContact: false
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
hasMention: false
editMode: false
isReply: true
@@ -807,7 +818,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
contactType: 0
isMutualContact: false
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
hasMention: false
editMode: false
isReply: false
@@ -834,7 +846,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
contactType: 0
isMutualContact: true
trustIndicator: StatusContactVerificationIcons.TrustedType.None
hasMention: false
editMode: false
isReply: false
@@ -861,7 +874,8 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
profileImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDKExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
isIdenticon: true
chatKey: "0x04d1bed19c523299cbd07ddec7b8949ad7dd923819a68e0b733c9c0bc38cde276bd256f098e755f8f028395c2c91f438a22adaff6caded060b7cc0ef3f470f1234"
contactType: 0
isMutualContact: true
trustIndicator: StatusContactVerificationIcons.TrustedType.None
hasMention: false
editMode: false
isReply: false
@@ -883,44 +897,66 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
nickName: "This is an example"
userName: "annabelle"
chatKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
trustIndicator: StatusMemberListItem.TrustedType.Verified
trustIndicator: StatusContactVerificationIcons.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: StatusMemberListItem.TrustedType.Untrustworthy
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
isMutualContact: false
isOnline: false
source: ""
isIdenticon: false
isIdenticon: false
}
ListElement {
nickName: "This girl I know from work"
userName: "annabelle"
chatKey: ""
trustIndicator: StatusMemberListItem.TrustedType.None
trustIndicator: StatusContactVerificationIcons.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: StatusMemberListItem.TrustedType.Untrustworthy
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
isMutualContact: true
isOnline: false
source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
isIdenticon: true
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}]
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

-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;
}
+10
View File
@@ -229,6 +229,11 @@ 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"
@@ -288,6 +293,11 @@ StatusWindow {
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusColorSelectorGrid"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
}
}
}
@@ -0,0 +1,36 @@
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
}
}
+83 -1
View File
@@ -57,6 +57,33 @@ 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
@@ -102,10 +129,24 @@ 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.component: StatusIcon {
input.rightComponent: StatusIcon {
icon: "cancel"
height: 16
color: Theme.palette.dangerColor1
@@ -130,4 +171,45 @@ 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
@@ -0,0 +1,75 @@
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("5 USER LIMIT REACHED")
warningText: qsTr("USER LIMIT REACHED")
}
}
+9 -3
View File
@@ -1,4 +1,10 @@
make clean
qmake sandbox.pro -spec macx-clang CONFIG+=debug CONFIG+=x86_64 && /usr/bin/make qmake_all
make
#!/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
+5 -1
View File
@@ -15,7 +15,7 @@ Column {
width: 288
property string categoryId: ""
property var model: []
property var model: null
property bool draggableItems: false
property alias statusChatListItems: statusChatListItems
@@ -97,10 +97,12 @@ 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
@@ -108,6 +110,8 @@ Column {
sensor.cursorShape: dragSensor.cursorShape
onClicked: {
highlightWhenCreated = false
if (mouse.button === Qt.RightButton && !!statusChatList.popupMenu) {
statusChatListItem.highlighted = true
@@ -48,7 +48,6 @@ Column {
popupMenuSlot.item.popup(mouse.x + 4, mouse.y + 6);
return
}
statusChatListCategory.opened = !opened;
}
}
onTitleClicked: statusChatListCategory.opened = !opened
@@ -5,6 +5,7 @@ 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
@@ -28,10 +29,14 @@ Rectangle {
width: 24
height: 24
color: Theme.palette.miscColor5
letterSize: 15
letterSize: emoji ? 11 : 15
emoji: ""
emojiSize: Emoji.size.verySmall
charactersLen: 1
}
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
@@ -145,12 +150,14 @@ 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,6 +14,7 @@ StatusListItem {
components: [
StatusBadge {
visible: statusContactRequestsListItem.requestsCount > 0
value: statusContactRequestsListItem.requestsCount
anchors.verticalCenter: parent.verticalCenter
border.width: 4
@@ -0,0 +1,79 @@
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
}
}
@@ -1,13 +1,17 @@
import QtQuick 2.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
Rectangle {
id: statusLetterIdenticon
id: root
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
@@ -16,15 +20,30 @@ Rectangle {
StatusBaseText {
id: identiconText
text: ((statusLetterIdenticon.name.charAt(0) === "#")
|| (statusLetterIdenticon.name.charAt(0) === "@") ?
statusLetterIdenticon.name.charAt(1) : statusLetterIdenticon.name.charAt(0)).toUpperCase()
anchors.alignWhenCentered: false
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
width: parent.width
height: parent.height
font.weight: Font.Bold
font.pixelSize: statusLetterIdenticon.letterSize
font.pixelSize: root.letterSize
color: Qt.rgba(255, 255, 255, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
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()
}
}
}
+64 -67
View File
@@ -13,8 +13,6 @@ 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: ""
@@ -22,8 +20,11 @@ Rectangle {
property real rightPadding: 16
property bool enabled: true
property bool highlighted: false
property bool propagateTitleClicks: true
property int type: StatusListItem.Type.Primary
property list<Item> components
property var bottomModel: []
property Component bottomDelegate
property StatusIconSettings icon: StatusIconSettings {
height: isLetterIdenticon ? 40 : 20
@@ -31,6 +32,7 @@ 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 {
@@ -52,31 +54,10 @@ Rectangle {
height: 40
isIdenticon: false
}
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 StatusIdenticonRingSettings ringSettings: StatusIdenticonRingSettings {
initalAngleRad: 0
ringPxSize: 1.5
distinctiveColors: Theme.palette.identiconRingColors
}
property alias sensor: sensor
@@ -84,10 +65,12 @@ 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
signal clicked(string itemId)
signal titleClicked(string titleId)
@@ -99,7 +82,12 @@ Rectangle {
}
implicitWidth: 448
implicitHeight: Math.max(64, statusListItemTitleArea.height + 16)
implicitHeight: {
if (bottomModel.length === 0) {
return Math.max(64, statusListItemTitleArea.height + 16)
}
return Math.max(64, statusListItemTitleArea.height + 90)
}
color: {
if (sensor.containsMouse || statusListItem.highlighted) {
switch(type) {
@@ -150,16 +138,26 @@ 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: statusListItem.leftPadding
anchors.right: statusListItemLabel.visible ? statusListItemLabel.left : statusListItemComponentsSlot.left
anchors.leftMargin: iconOrImage.active ? 16 : statusListItem.leftPadding
anchors.rightMargin: statusListItem.rightPadding
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenter: bottomModel.length === 0 ? parent.verticalCenter : undefined
height: childrenRect.height
StatusBaseText {
@@ -169,8 +167,9 @@ Rectangle {
height: visible ? contentHeight : 0
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
anchors.left: parent.left
anchors.right: !statusListItem.titleAsideText && !statusListItem.titleIcon1Visible && !statusListItem.titleIcon2Visible
? parent.right : undefined
anchors.right: !statusListItem.titleAsideText && !titleIconsRow.sourceComponent ? parent.right : undefined
anchors.top: bottomModel.length === 0 ? undefined: parent.top
anchors.topMargin: bottomModel.length === 0 ? undefined : 20
color: {
if (!statusListItem.enabled) {
return Theme.palette.baseColor1
@@ -187,9 +186,10 @@ Rectangle {
MouseArea {
anchors.fill: parent
cursorShape: containsMouse? Qt.PointingHandCursor : Qt.ArrowCursor
enabled: statusListItem.enabled
cursorShape: sensor.enabled && containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
hoverEnabled: true
propagateComposedEvents: true
propagateComposedEvents: statusListItem.propagateTitleClicks
onClicked: {
statusListItem.titleClicked(statusListItem.titleId)
mouse.accepted = false
@@ -202,43 +202,20 @@ 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
}
Row {
Loader {
id: titleIconsRow
spacing: 4
anchors.left: !statusListItem.titleAsideText ? statusListItemTitle.right : statusListItemTitleAsideText.right
anchors.verticalCenter: statusListItemTitle.verticalCenter
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
}
}
anchors.leftMargin: 4
}
StatusBaseText {
id: statusListItemSubTitle
@@ -270,11 +247,30 @@ Rectangle {
width: contentItem.width
implicitHeight: visible ? 22 : 0
}
}
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: parent.verticalCenter
anchors.verticalCenter: bottomModel.length === 0 ? parent.verticalCenter : undefined
anchors.top: bottomModel.length === 0 ? undefined: parent.top
anchors.topMargin: bottomModel.length === 0 ? undefined : 16
anchors.right: statusListItemComponentsSlot.left
anchors.rightMargin: statusListItemComponentsSlot.width > 0 ? 10 : 0
@@ -284,12 +280,13 @@ Rectangle {
visible: !!statusListItem.label
}
Row {
id: statusListItemComponentsSlot
anchors.right: parent.right
anchors.rightMargin: statusListItem.rightPadding
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenter: bottomModel.length === 0 ? parent.verticalCenter : undefined
anchors.top: bottomModel.length === 0 ? undefined: parent.top
anchors.topMargin: bottomModel.length === 0 ? undefined : 12
spacing: 10
}
}
@@ -57,6 +57,8 @@ 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
@@ -0,0 +1,81 @@
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,15 +10,9 @@ StatusListItem {
property string userName: ""
property string chatKey: ""
property bool isMutualContact: false
property var trustIndicator: StatusMemberListItem.TrustedType.None
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
property bool isOnline: false
enum TrustedType {
None, //0
Verified, //1
Untrustworthy //2
}
// Subtitle composition:
function composeSubtitile() {
var compose = ""
@@ -42,8 +36,10 @@ StatusListItem {
// root object settings:
title: root.nickName
titleIcon1Visible: root.isMutualContact
titleIcon2Visible: root.trustIndicator !== StatusMemberListItem.TrustedType.None
statusListItemTitleIcons.sourceComponent: StatusContactVerificationIcons {
isMutualContact: root.isMutualContact
trustIndicator: root.trustIndicator
}
subTitle: composeSubtitile()
statusListItemSubTitle.font.pixelSize: 10
icon.isLetterIdenticon: !root.image.source.toString()
@@ -51,7 +47,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
@@ -64,13 +60,4 @@ 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
}
+2 -13
View File
@@ -21,14 +21,6 @@ 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
@@ -108,11 +100,8 @@ Rectangle {
displayName: messageDetails.displayName
secondaryName: messageDetails.secondaryName
tertiaryDetail: messageDetails.chatID
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
isMutualContact: messageDetails.isMutualContact
trustIndicator: messageDetails.trustIndicator
resendText: statusMessage.resendText
showResendButton: messageDetails.hasExpired && messageDetails.amISender
onClicked: statusMessage.senderNameClicked()
@@ -17,12 +17,13 @@ QtObject {
property string messageText: ""
property int contentType: 0
property string messageContent: ""
property int contactType: 0
property bool isMutualContact: false
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
property bool hasMention: false
property bool isPinned: false
property string pinnedBy: ""
property bool hasExpired: false
property string timestamp: ""
property string timestamp: ""
}
@@ -1,11 +1,13 @@
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
@@ -13,6 +15,7 @@ Loader {
property StatusIconSettings icon: StatusIconSettings {
width: 40
height: 40
charactersLen: 1
}
property StatusImageSettings image: StatusImageSettings {
@@ -20,6 +23,12 @@ 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
@@ -75,10 +84,21 @@ 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
@@ -88,6 +108,6 @@ Loader {
border.width: 3
implicitHeight: 15
implicitWidth: 15
z: 100
z: statusSmartIdenticon.dZ
}
}
+203 -44
View File
@@ -1,6 +1,7 @@
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
@@ -9,29 +10,57 @@ Item {
id: root
implicitWidth: 448
implicitHeight: 44
implicitHeight: 44 + ((userListView.count > 0) ? 44 + ((((userListView.count * 64) > root.maxHeight)
? root.maxHeight : (userListView.count * 64))) :0)
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 {
anchors.fill: parent
id: tagSelectorRect
width: parent.width
height: 44
radius: 8
color: Theme.palette.baseColor2
@@ -47,47 +76,54 @@ Item {
text: root.toLabelText
}
ListView {
id: namesList
Layout.preferredWidth: (count >= 5) ? (parent.width - warningTextLabel.width - 30) : childrenRect.width
ScrollView {
Layout.preferredWidth: (namesList.contentWidth > (parent.width - 142)) ?
(parent.width - 142) : namesList.contentWidth
implicitHeight: 30
visible: (count > 0)
Layout.alignment: Qt.AlignVCenter
model: namesModel
orientation: ListView.Horizontal
spacing: 8
visible: (namesList.count > 0)
contentWidth: namesList.contentWidth
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
clip: true
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
ListView {
id: namesList
anchors.fill: parent
model: namesModel
orientation: ListView.Horizontal
spacing: 8
onCountChanged: {
contentX = contentWidth;
}
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);
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);
}
}
}
}
@@ -106,7 +142,8 @@ Item {
color: Theme.palette.directColor1
Keys.onPressed: {
if ((event.key === Qt.Key_Backspace || event.key === Qt.Key_Escape)
&& getText(cursorPosition, (cursorPosition-1)) === "") {
&& getText(cursorPosition, (cursorPosition-1)) === "") {
removeMember(namesModel.get(namesList.count-1).publicId);
namesModel.remove((namesList.count-1), 1);
}
}
@@ -114,12 +151,134 @@ Item {
StatusBaseText {
id: warningTextLabel
visible: (namesModel.count === 5)
visible: (namesModel.count === root.nameCountLimit)
Layout.preferredWidth: 120
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
font.pixelSize: 10
color: Theme.palette.dangerColor1
text: root.warningText
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);
}
}
}
}
}
@@ -19,38 +19,8 @@ Item {
property string tertiaryDetail: ""
property string resendText: ""
property bool showResendButton: false
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
}
}
property bool isMutualContact: false
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
signal clicked()
signal resendClicked()
@@ -83,28 +53,10 @@ Item {
}
}
Layout.alignment: Qt.AlignBottom
}
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
}
StatusContactVerificationIcons {
isMutualContact: statusMessageHeader.isMutualContact
trustIndicator: statusMessageHeader.trustIndicator
}
StatusBaseText {
id: secondaryDisplayName
+2
View File
@@ -10,6 +10,7 @@ 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
@@ -22,6 +23,7 @@ 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
+189 -150
View File
@@ -1,14 +1,15 @@
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: statusBaseInput
id: root
property bool multiline: false
@@ -24,6 +25,7 @@ Item {
property alias edit: edit
property alias text: edit.text
property alias background: background
property alias color: edit.color
property alias font: edit.font
@@ -35,10 +37,11 @@ Item {
property alias placeholderTextColor: placeholder.color
property alias placeholderFont: placeholder.font
property real leftPadding: 16
property real leftPadding: leftComponentLoader.item ? 8 : 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
@@ -49,56 +52,64 @@ 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
}
property Item component
onClearableChanged: {
if (clearable && !component) {
clearButtonLoader.active = true
clearButtonLoader.parent = statusBaseInputComponentSlot
} else {
clearButtonLoader.active = false
emoji: ""
letterSize: emoji ? 11 : 14
background: StatusIconBackgroundSettings {
width: 30
height: 30
color: Theme.palette.indirectColor1
}
}
onComponentChanged: {
if (!!component) {
component.parent = statusBaseInputComponentSlot
}
}
property Component leftComponent
property Component rightComponent
signal iconClicked
signal keyPressed(var event)
signal editClicked()
implicitWidth: 448
implicitHeight: multiline ? Math.max((edit.implicitHeight + topPadding + bottomPadding), 44) : 44
implicitHeight: multiline ? Math.min(Math.max(
(edit.implicitHeight + topPadding + bottomPadding),
44, root.minimumHeight), root.maximumHeight) : 44
Rectangle {
id: background
width: parent.width
height: maximumHeight != 0 ? Math.min(
minimumHeight != 0 ? Math.max(statusBaseInput.implicitHeight, minimumHeight)
: statusBaseInput.implicitHeight, maximumHeight) : parent.height
color: Theme.palette.baseColor2
minimumHeight
!= 0 ? Math.max(
root.implicitHeight,
minimumHeight) : root.implicitHeight,
maximumHeight) : parent.height
color: root.showBackground ? Theme.palette.baseColor2
: "transparent"
radius: 8
clip: true
border.width: 1
border.color: {
if (!statusBaseInput.valid && statusBaseInput.dirty) {
return Theme.palette.dangerColor1;
if (!root.showBackground) {
return "transparent"
}
if (!root.valid && root.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
@@ -107,146 +118,138 @@ Item {
cursorShape: Qt.IBeamCursor
onClicked: {
edit.forceActiveFocus()
root.editClicked()
}
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
RowLayout {
anchors {
fill: parent
leftMargin: root.leftPadding
rightMargin: root.rightPadding
}
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
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;
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
}
}
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
}
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
}
Keys.onReturnPressed: {
if (multiline) {
event.accepted = false
} else {
event.accepted = true
}
}
TextEdit {
id: edit
Keys.onEnterPressed: {
if (multiline) {
event.accepted = false
} else {
event.accepted = true
}
}
property string previousText: text
property var keyEvent
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: statusBaseInput.rightPadding
anchors.verticalCenter: parent.verticalCenter
width: flick.width
height: flick.height
verticalAlignment: Text.AlignVCenter
selectByMouse: true
selectionColor: Theme.palette.primaryColor2
selectedTextColor: color
focus: true
font.pixelSize: 15
elide: StatusBaseText.ElideRight
font.family: Theme.palette.baseFont.name
color: statusBaseInput.enabled ? Theme.palette.baseColor1 :
Theme.palette.directColor6
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);
}
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
}
}
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
}
}
} // 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
}
}
} // Flickable
Item {
id: statusBaseInputComponentSlot
anchors.right: parent.right
anchors.rightMargin: 12
width: childrenRect.width
height: childrenRect.height
anchors.verticalCenter: parent.verticalCenter
}
}
} // Rectangle
Loader {
id: clearButtonLoader
sourceComponent: StatusFlatRoundButton {
id: clearButton
visible: edit.text.length != 0 &&
statusBaseInput.clearable &&
!statusBaseInput.multiline &&
edit.activeFocus
Component {
id: clearButton
StatusFlatRoundButton {
visible: edit.text.length != 0 && root.clearable && !root.multiline
&& edit.activeFocus
type: StatusFlatRoundButton.Type.Secondary
width: 24
height: 24
@@ -260,5 +263,41 @@ 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
}
}
}
@@ -0,0 +1,32 @@
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
}
}
}
@@ -0,0 +1,56 @@
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]
}
}
}
}
}
}
@@ -0,0 +1,132 @@
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
}
}
}
}
}
}
+124 -15
View File
@@ -6,27 +6,71 @@ 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
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
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
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
@@ -35,27 +79,73 @@ 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
Always, // validates input even before it has become dirty
IgnoreInvalidInput // ignore the new content if it doesn't match
}
property var errors: ({})
property var asyncErrors: ({})
function reset() {
statusBaseInput.valid = false
statusBaseInput.valid = true
statusBaseInput.pristine = true
statusBaseInput.text = ""
root.errorMessage = ""
}
property string _previousText: text
function validate() {
if (!statusBaseInput.dirty && validationMode === StatusInput.ValidationMode.OnlyWhenDirty) {
return
}
@@ -85,11 +175,23 @@ 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) {
@@ -189,6 +291,13 @@ Item {
onTextChanged: root.validate()
Keys.forwardTo: [root]
onIconClicked: root.iconClicked()
onKeyPressed: {
root.keyPressed(event);
}
onEditChanged: {
root.editClicked();
}
}
StatusBaseText {
@@ -15,16 +15,23 @@ StatusProgressBar {
property string labelGreat: "Great"
enum Strength {
VeryWeak, // 0
Weak, // 1
SoSo, // 2
Good, // 3
Great // 4
None, // 0
VeryWeak, // 1
Weak, // 2
SoSo, // 3
Good, // 4
Great // 5
}
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
@@ -0,0 +1,234 @@
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 } }
}
}
@@ -0,0 +1,181 @@
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
/*!
\qmltype StatusSeedPhraseInput
\inherits Item
\inqmlmodule StatusQ.Controls
\since StatusQ.Controls 0.1
\brief Displays a text input with suggestions. Inherits \l{https://doc.qt.io/qt-5/qml-qtquick-item.html}{Item}.
The \c StatusSeedPhraseInput item displays a text input with suggestions filtered based on the typed text.
For example:
\qml
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
leftComponentText: "1"
inputList: ListModel {
ListElement {
seedWord: "panda"
}
ListElement {
seedWord: "posible"
}
ListElement {
seedWord: "wing"
}
}
}
\endqml
For a list of components available see StatusQ.
*/
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)
/*
This signal is emitted when the user pressed a keyboard key and passes as a
parameter the event. The corresponding handler is \c onKeyPressed.
*/
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 === 4) && (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;
}
}
}
}
}
}
@@ -0,0 +1,170 @@
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
}
}
}
}
}
}
@@ -0,0 +1,57 @@
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
}
}
}
@@ -0,0 +1,57 @@
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
}
}
@@ -0,0 +1,60 @@
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,6 +6,7 @@ QtObject {
property string name: ""
property string errorMessage: "invalid input"
property var validatorObj
property var validate: function (value) {
return true
+3
View File
@@ -4,7 +4,10 @@ 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,6 +8,7 @@ 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
@@ -24,10 +25,14 @@ 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
+4
View File
@@ -8,10 +8,14 @@ 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 {}
}
@@ -0,0 +1,66 @@
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,6 +158,13 @@ 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,6 +156,13 @@ 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,6 +92,8 @@ QtObject {
property var accountColors: []
property var identiconRingColors: []
property QtObject statusAppLayout: QtObject {
property color backgroundColor
property color rightPanelBackgroundColor
+120
View File
@@ -0,0 +1,120 @@
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,6 +70,10 @@ 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
+2 -1
View File
@@ -1,4 +1,5 @@
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,6 +4,7 @@ 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
+183 -2
View File
@@ -5,19 +5,186 @@ 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
property StatusModalHeaderSettings header: StatusModalHeaderSettings {}
/*!
\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 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()
@@ -64,11 +231,25 @@ 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,8 +21,6 @@ Menu {
property var closeHandler
dim: true
Overlay.modeless: MouseArea {}
signal menuItemClicked(int menuIndex)
@@ -10,6 +10,7 @@ StatusPopupMenu {
property var searchPopup
property var locationModel
readonly property int numDefaultItems: 2
signal itemClicked(string firstLevelItemValue, string secondLevelItemValue)
@@ -43,7 +44,7 @@ StatusPopupMenu {
color: model.iconColor,
isLetterIdenticon: !model.imageSource && !model.iconName
});
root.insertMenu(index+2, item);
root.insertMenu(index + numDefaultItems, item);
} else {
item.value = model.value
item.text = model.title;
@@ -52,7 +53,7 @@ StatusPopupMenu {
item.iconSettings.isLetterIdenticon = !model.imageSource && !model.iconName
item.image.source = model.imageSource;
item.image.isIdenticon = model.isIdenticon;
root.insertItem(index+2, item);
root.insertItem(index + numDefaultItems, item);
}
}
}
+15 -4
View File
@@ -20,10 +20,13 @@ StatusModal {
property string searchText: contentItem.searchText
property string noResultsLabel: "No results"
property string defaultSearchLocationText: "Anywhere"
property bool loading
property bool loading: false
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)
@@ -52,7 +55,7 @@ StatusModal {
}
function forceActiveFocus() {
contentItem.searchInput.forceActiveFocus()
contentItem.searchInput.edit.forceActiveFocus()
}
onOpened: {
@@ -82,7 +85,8 @@ StatusModal {
icon: "search"
color: Theme.palette.baseColor1
}
TextEdit {
StatusBaseInput {
id: inputText
anchors.left: statusIcon.right
anchors.leftMargin: 15
@@ -91,6 +95,10 @@ 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: {
@@ -275,8 +283,11 @@ StatusModal {
root.resultItemClicked(itemId)
}
propagateTitleClicks: !root.acceptsTitleClick(titleId)
onTitleClicked: {
root.resultItemTitleClicked(titleId)
if (root.acceptsTitleClick(titleId)) {
root.resultItemTitleClicked(titleId)
}
}
}
section.property: "sectionName"
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

+3
View File
@@ -0,0 +1,3 @@
<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>

After

Width:  |  Height:  |  Size: 632 B

+3
View File
@@ -0,0 +1,3 @@
<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>

After

Width:  |  Height:  |  Size: 820 B

+3
View File
@@ -0,0 +1,3 @@
<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>

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

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