Compare commits

...
181 Commits
Author SHA1 Message Date
Igor Sirotin 1bdc330c3f feat(Theme): Added radius and bigPadding properties 2022-05-27 16:29:45 +03:00
Igor Sirotin 485647d1c3 feat(StatusTabButton): Created component as per design (#684) 2022-05-23 14:29:42 +03:00
Alexandra Betouni e1db639340 feat(StatusTagSelector): Replaced member delegate w/ StatusMemberLisItm (#676)
Fixes https://github.com/status-im/status-desktop/issues/5625
2022-05-19 12:02:36 +03:00
Boris Melnik b918897241 fix(StatusTagSelector): Fix mouse hover (#678)
Closes: status-im/status-desktop#5220
2022-05-19 11:42:18 +03:00
Alexandra Betouni 6ba2d8f3e6 fix(StatusChatList): Fixed alignment in left column (#680)
Needed for https://github.com/status-im/status-desktop/issues/5211
2022-05-18 17:01:27 +03:00
Igor Sirotin c01f623305 fix(StatusLetterIdentIcon): Display emoji as svg (#677)
* fix(StatusLetterIdentIcon): Display emoji as svg

* feat(StatusEmoji): Added StatusEmoji image component
2022-05-17 21:16:11 +03:00
r4bbit.eth 6dc6ebb2fb fix(StatusSeedPhraseInput): ensure suggested item has correct text color (#670) 2022-05-13 14:24:24 -04:00
Igor Sirotin 2d031244ca fix(StatusSlider): Fixed background behavior (#667) 2022-05-13 14:24:07 -04:00
Mikhail Rogachev 9498be05ef fix(StatusProgressBar): Hide text in bar if it does not fit (#672) 2022-05-13 14:05:37 -04:00
Igor Sirotin 1b25ddd2b5 feat(Emoji): Functions improvements (#673)
- Introduced `format] argument for `parse` function
- New `iconId(text)` function
2022-05-13 14:01:48 -04:00
Alexandra Betouni 9741f98b70 fix(StatusSeedPhraseInput): anchored component to its parent bottom
Needed for: https://github.com/status-im/status-desktop/issues/5669
2022-05-13 16:29:35 +02:00
Alexandra Betouni 02923f7947 feat(StatusInput): exposed letterIconName property (#671)
Exposed letterIconName to be set in StatusLetterIdenticon

Needed for: https://github.com/status-im/status-desktop/issues/5636
2022-05-13 13:38:49 +03:00
Jonathan Rainville 6c5957a492 fix(StatusTagSelector): hide contact when it is selected (#668) 2022-05-12 16:27:35 -04:00
Jonathan Rainville eb96e5e08d fix(StatusSeedPhraseInput): autocomplete when word not alone in the list
The problem was that if the clicked word (or tabbed) was not alone in the suggestion list, the done signal was not called. Now it is always called when clicking on using tab or enter.
2022-05-12 10:00:06 -04:00
Stefan 457e5fe4af fix(StatusSlider): improve handle draging area
Issues
- The slider only handle mouse events in its own control space.
- In oder to use the entire area it needs to be centered.

Fixes

- Center the content vertically (handle and slider bar)
- Height and implicitHeight defaults to heigh of the handle
- Add note to create awareness about the mouse handling requirements
2022-05-11 19:30:04 +03:00
Stefan 1c0d4b0133 improvement(StatusImageCrop): add option to limit to fill
Currently only fit image is supported as minimum limit
This change sdds option to fill crop window with image as
minimum zoom which is required by status-go crop function
2022-05-11 18:06:26 +03:00
Alexandra Betouni ba79f62fda fix(StatusTagSelector): Updated names list filtering (#659)
Fixes: https://github.com/status-im/status-desktop/issues/5642
2022-05-11 12:01:14 +03:00
Jonathan Rainville a9c79b0359 fix(StatusBaseInput): adjust emoji size and position in base input (#660) 2022-05-10 15:17:22 -04:00
Alexandra Betouni a668afef35 fix(StatusTagSelector): Adjusted name tags list width and scrolling (#653)
Needed for https://github.com/status-im/status-desktop/issues/5643
2022-05-10 19:04:27 +03:00
Patryk Osmaczko deb8b38b1f chore(translations): add missing qsTrs
issue: status-im/status-desktop#4544
2022-05-10 17:52:34 +02:00
Khushboo Mehta b4ebc520e1 fix(StatusBaseButton): Button component should keep its original width/size when it enters loading state
fixes #656
2022-05-10 10:53:45 +02:00
mishkarogachev 5def2102c7 fix(StatusTagSelector):Create new chat input is single line 2022-05-10 10:52:49 +02:00
mishkarogachev 0f511ebc60 fix(StatusListItem): Make text always fit boundaries 2022-05-10 07:44:25 +02:00
Alexandra Betouni b09210cf1f fix(StatusTagSelector): Added up/down hard keys navigation
Needed for: https://github.com/status-im/status-desktop/issues/5640
2022-05-10 07:42:01 +02:00
Noelia 3bdfc3e528 fix(StatusBaseButton): After loading, button keeps loader width, so the button size is bigger
When button changed from loading to their normal shape it kept the width of the loader as it was visible in the row component.

It has been added a binding between loader `visible` property and root `loading` property that fixes the issue with the width.

Also, removed some `break` leftovers.

Fixes #5606 --> https://github.com/status-im/status-desktop/issues/5606
2022-05-10 07:41:45 +02:00
mishkarogachev baf5948c90 fix(StatusSwitchTabBar): Update and unify colors of tabBar 2022-05-10 07:41:15 +02:00
Jonathan Rainville 4b1516c990 fix(StatusWizardStepper): make to value configurable 2022-05-10 07:40:56 +02:00
Jonathan Rainville 1a5990f24b fix(StatusBaseInput): fix typo in verticalAlignement 2022-05-10 07:40:56 +02:00
Khushboo Mehta 82e1845056 fix(StatusListPicker): Add an option to allign the menu with respective the buttons and keep right aligned as the default one
Also fixes search placeholder to be centrally aligned

fixes #5633
2022-05-10 07:40:26 +02:00
Jonathan Rainville 75a76afcf1 fix(StatusSeedPhraseInput): fix pasting word with spaces in them
This makes it possible to paste a word with a space in it. It will insert it correctly
2022-05-09 13:02:30 -04:00
Jonathan Rainville 0922cf507a fix(StatusSeedPhraseInput): fix interactions in SeedInput 2022-05-09 13:02:30 -04:00
Jonathan Rainville 32c5f7f8df feat(StatusBasenput): add acceptReturn to Input to pass return events 2022-05-09 13:02:30 -04:00
Jonathan Rainville 148505ba6b fix(StatusBaseInput): fix dirty being set when the text didn't change 2022-05-06 20:07:36 +02:00
Sale Djenic d960c6dcec feat(StatusToastMessage): introduce duration property and close signal emit after animation
- `open` property set to `true` by default
- `duration` property added (if set to anything greater than 0, will trigger
close toast signal after `duration` milliseconds)
- `close` signal is now emitted once animation gets completed
2022-05-06 07:51:19 +02:00
Stefan bb9f08155f fix(StatusImageCrop): output an error if trying to set cropRect without image 2022-05-05 17:16:13 +02:00
Stefan 934db52126 test(Components.StatusImageCropPanel): basic validation tests for the image crop component
updates #5401
2022-05-05 17:16:13 +02:00
Stefan dcef08f3b3 test(Controls.StatusImageCrop): basic validation tests for the image crop control
updates #5401
2022-05-05 17:16:13 +02:00
Stefan 20e7b345e1 tests(general): refactor tests
Enhance the CMake strucuture of thests
Update documentation
2022-05-05 17:16:13 +02:00
Stefan 5f8453659d feat(Sandbox): add visual test setup page for StatusImageCropPanel
Other improvements:

- save state for theme switcher and last selected page
- add optional fill all test space for pages

fixes: 5401
2022-05-05 17:16:13 +02:00
Stefan c7ff011649 feat(StatusImageCropPanel): Add image crop editor panel component
New QML component StatusQ.Components.StatusImageCropPanel
that extends on StatusImageCrop with simper interface and extra features

Features:
- Minimizes drawing with Canvas to the crop window
- Adds user interactions: pan, zoom
- Zoom slider for zooming, beside the mouse scroll action
- Optional checker pattern for background for the user to have a visual feedback on the transparent areas or image margins

fixes: #5401
updates: #5118
2022-05-05 17:16:13 +02:00
Stefan 2b71ccf50f feat(StatusImageCrop): Image cropping editor control
New QML control StatusQ.Controls.StatusImageCrop allows user to crop an image for avatar/banner purpuses

Features:
- Support rectangular and elliptical crop windows
- Transparency for the wall
- Controlling the crop window in image coordinates using cropRect
- The image support is based on `Image`
- Limits the

fixes: #5401
2022-05-05 17:16:13 +02:00
Alexandra Betouni 310be728a3 fix(StatusChatList): Added property to control item's highlight (#646)
Needed for https://github.com/status-im/status-desktop/issues/5627
2022-05-05 12:27:05 +03:00
Igor Sirotin e2728285e1 build: Added all qmls and assets to resources (fixes release build) (#647) 2022-05-04 21:19:46 +03:00
Igor Sirotin 1d9abf8e95 fix(StatusBaseInput): Fixed border color on active focus loss (#643) 2022-05-03 19:08:40 +03:00
Igor Sirotin 31e90c2d47 fix(StatusBaseInput): Implement cursor as per designs (#642) 2022-05-03 19:08:02 +03:00
Noelia ae1e72fb23 fix(StatusListPicker): Disable uncheck option and reset searcher (#639)
Disabled uncheck option if component is configured as single selection mode.

Added binding to reset searcher input text when picker is closed.

BREAKING CHANGE: Renamed `searchText` property for `placeholderSearchText` to control placeholder text in searcher and added / used existing `searchText` property to control  searcher input text.
2022-05-03 10:45:36 +02:00
Stefan Dunca 7710470559 doc(contributing.md): add pixel miss-alignment recommendation
Follow up on the PR comment https://github.com/status-im/status-desktop/pull/5549#issuecomment-1099468321
2022-04-16 20:28:27 +02:00
Michal Iskierko 2069399979 fix(StatusTagSelector): Fix displaying a list of contacts in StatusTagSelector
Fix #5465
2022-04-13 12:30:02 +02:00
Alexandra Betouni 29dd4da2e4 fix(StatusSearchLocationMenu): removed dimming from submenus (#635)
fixes https://github.com/status-im/status-desktop/issues/5139
2022-04-11 17:33:53 -04:00
Patryk Osmaczko 394040a039 chore(StatusChatList): use colorId if color is not provided 2022-04-08 13:19:00 +02:00
Patryk Osmaczko a8e1ed863c chore(StatusLetterIdenticon): test different backgrounds 2022-04-08 13:19:00 +02:00
Patryk Osmaczko d7b1ae9fbc fix(StatusIdenticonRing): repait ring when model changes 2022-04-08 13:19:00 +02:00
Patryk Osmaczko f0c7d950ea chore(ThemePalette): introduced userCustomizationColors
BREAKING CHANGE: renamed accountColors to userCustomizationColors
2022-04-08 13:19:00 +02:00
Patryk Osmaczko 1e5d389b53 feat(StatusLetterIdenticon): use luminance to determine letter color 2022-04-08 13:19:00 +02:00
Alexandra Betouni 1cda85fc0e feat(StatusInput): Adding component documentation (#632)
Part of #616
2022-04-07 16:51:21 -04:00
Alexandra Betouni 4999368dfe feat(StatusBaseInput): Adding component documentation (#631)
Part of #616
2022-04-07 16:50:36 -04:00
Noelia 7e4d69be05 feat(StatusPasswordStrengthIndicator): Added component documentation (#630)
Added component documentation.

Part of #620
2022-04-07 16:50:23 -04:00
Noelia 3abbd3d4cd feat(StatusMemberListItem): Added component documentation (#629)
Added component documentation and updated functions to be private.

Part of #620
2022-04-07 16:50:09 -04:00
Noelia 8fc5276090 feat(StatusBanner): Added component documentation (#628)
Added component documentation.

Part of #620
2022-04-07 16:49:44 -04:00
Alexandra Betouni cf4b092112 feat(StatusTagSelector): Adding component documentation (#623)
Part of #616
2022-04-07 16:49:14 -04:00
Alexandra Betouni ddf4a8d4f1 feat(StatusToastMessage): Adding component documentation (#621)
Part of #616
2022-04-07 16:49:02 -04:00
Alexandra Betouni 9c1edc80db feat(StatusSeedPhraseInput): Adding component documentation (#617)
Also fixed component's height in demonstration page

Part of #616
2022-04-07 16:48:43 -04:00
Alexandra Betouni 20bf5b07a6 fix(StatusTagSelector): adding wrap mode in text edit (#633)
needed for: https://github.com/status-im/status-desktop/issues/5294
2022-04-07 16:12:12 -04:00
Noelia ade6bd2d0d fix(StatusPickerButton): Added property textPixelSize to be configurable (#626)
Added property `textPixelSize` to be configurable in `StatusPickerButton`.
2022-04-07 11:13:37 -04:00
Noelia 125760b934 fix(StatusItemPicker): Updated selected property properly and documentation improvements. (#625)
Updated `selected` property properly.

Some documentation improvements.
2022-04-07 11:13:13 -04:00
Noelia e231c0a6cb fix(StatusListPicker/StatusItemPicker/StatusPickerButton): Added some properties / signals (#624)
Added property `textPixelSize` to be configurable in `StatusPickerButton`.

Added signal `itemPickerChanged` to be directly notified when an item changes its selected property value.

Updated `selected` property properly in `StatusListPicker`.

Added new property `enableSelectableItem` to highlight an item when hovering.

Some documentation improvements.
2022-04-07 11:12:57 -04:00
Pascal Precht a16bc6bb6e fix(StatusSeedPhraseInput): don't access input control via root 2022-04-07 14:32:07 +02:00
Richard Ramos 51989c0f5d fix(StatusSeedPhraseInput): handle 3 characters mnemonics 2022-04-07 13:15:50 +02:00
Boris Melnik 88b7f6eab8 fix(StatusListItem): Show emoji if exist
Part of: https://github.com/status-im/status-desktop/issues/5350
2022-04-06 13:58:05 +02:00
Alexandra Betouni 2df3c0a03e feat(StatusWizardStepper): Adding component documentation (#618)
Part of #616
2022-04-06 10:22:15 +02:00
Anthony Laibe 1e9cc07e2d fix(StatusFloatValidator): Fix value equal to bottom 2022-04-05 11:54:23 +02:00
Patryk Osmaczko 6221c0a540 fix: add various fixes/improvements to identicons 2022-04-04 17:39:52 +02:00
Boris Melnik ddbffa7f28 feat(assets): Add new icons for community settings
Part of: status-im/status-desktop#4932
2022-04-04 15:25:31 +02:00
Noelia 555ad8bea8 feat(StatusQ.Components/Controls): New StatusListPicker and StatusItemPicker selector component / control (#583)
It adds the `StatusItemPicker` control and `StatusListPicker` component and its corresponding documentation.

The new selector component is composed by a `StatusButtonPicker` and a drop-down list.

It adds sections in `ListView` by using `category` model property.

It incorporates a searcher in header.

The selector type can be customised as a `StatusRadioButton` or a `StatusCheckbox`.

It adds dynamic selection mechanism.

It adds a dynamic text fit between `name` and `shortName` text components.

It adds a specific page in `sandbox` and some models to play with that.

It extends `StatusPickerButton` to allow more than one type.

Closes #563
2022-04-04 12:16:47 +02:00
Stefan Dunca a561a3fff8 Clarify dynamic scoping 2022-04-04 10:49:24 +03:00
Stefan 70ec009edd docs(General): initial proposal on developer documentation and checklists
Developer targeted checklist and reminders to cover the most common source of errors
and tech-debt (maintenance burden).
2022-04-04 10:49:24 +03:00
Alexandra Betouni 31a1c60eb1 fix(StatusTagSelector): fixing tag selector height (#606)
Fix for https://github.com/status-im/status-desktop/issues/5199
2022-04-01 17:26:35 +03:00
Alexandra Betouni 0a2cf6ab6e fix(StatusSeedPhraseInput): added trim() also when seedWord selected from list (#613)
Fixes issue on Windows where empty spaces are insterted in the input
field together with the word
2022-03-31 19:40:21 +03:00
Jonathan Rainville 07fa2a1b0c fix(StatusSeedPhraseInput): remove empty spaces in seed phrase input (#611) 2022-03-30 14:23:18 -04:00
Sale Djenic 43b8e43303 fix(@desktop/contacts): placeholder position updated 2022-03-30 18:30:21 +02:00
Alexandra BetouniandKhushboo-dev-cpp 2cec51ff8d feat(StatusSeedPhraseInput): exposed keys on pressed signal (#599)
* 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

* feat(StatusListItem): Added new tags inline in the StatusListItem (#607)

Co-authored-by: Khushboo-dev-cpp <60327365+Khushboo-dev-cpp@users.noreply.github.com>
2022-03-30 01:23:54 +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
Patryk Osmaczko 5780f183c7 feat(StatusListItem): add highlighted property 2022-02-09 10:00:41 +01:00
Alexandra Betouni b7d6554b80 feat(StatusQ.Components): Adding StatusWizardSteper component
Added StatusWizardStepper component

Also added corresponding page in API documentation

Closes #522
2022-02-09 09:21:46 +01:00
Pascal Precht 0fabd92d61 chore: cut 0.23.0 release 2022-02-08 09:40:35 +01:00
Alexandra Betouni 7b290ddd56 feat(StatusQ.Components): Adding StatusToastMessage
Added StatusToastMessage component, an example page
as well as a demonstration in chat view

Closes #521
2022-02-08 09:36:38 +01:00
Alexandra Betouni 094dee4928 feat(StatusQ.Components): Adding StatusTagSelector component
Added StatusTagSelector component needed for
creating new chat channels, either ono on
one or group based on updated designs on
Figma

Also added corresponding page in API Documentation

Closes #526
2022-02-02 10:26:45 +01:00
Noelia 5497bb3f5f chore(demoApp): restore DemoApp to have the latest changes from both master and base_bc
Updated DemoApp, main and Models to have the
latest changes from both master and base_bc
2022-02-02 10:18:03 +01:00
Richard Ramos d85ed4c3ed refactor: fix empty categories handling (#544)
* feat(StatusChatListCategory): display item if the model is a category
* fix(StatusChatListAndCategories): do not display categories in StatusChatList
2022-02-01 11:10:09 +01:00
Sale Djenic 77b89edbdb refactor(StatusAppNavBar): triggerUpdate function added 2022-02-01 11:10:09 +01:00
Sale Djenic 80396841f1 refactor(StatusChatToolBar): open/close handlers get called if they are set for popupMenu of StatusChatToolBar component 2022-02-01 11:10:09 +01:00
Sale Djenic c2e075178c fix(StatusChatList): unexisting property name for chat item fixed
`StatusChatList` component is able to display:
- chats for Chat section
- channels for Community section
- channels from a category from Community section

in cases 1. and 2. displayed items do not have `parentItemId` property and
it's not used in these cases.
This commit fixes that console error.
2022-02-01 11:10:09 +01:00
Sale Djenic e0f34a3e1d refactor(StatusChatList): categoryId parameter added to chatItemSelected signal 2022-02-01 11:10:09 +01:00
Sale Djenic c2bab872be refactor(StatusChatList): updates due to chat & communities models refactored
Updated Models.qml for chats and communities models to reflect changes due to
refactor in the actual backend.`StatusChatList` and `StatusChatListAndCategories`
components updated accordingly.
2022-02-01 11:10:09 +01:00
Alexandra Betouni 491f7d5d15 refactor(sandbox): remove obsolete timeline demo code
This feature is deprecated and shall be removed

Relates to #4177
2022-02-01 11:10:09 +01:00
Sale Djenic c6893b0c7f refactor(StatusAppNavBar): profile nav bar button added
Profile button of type `StatusNavBarTabButton` added to `StatusAppNavBar`
and exposed so it can be optionally set from outside of the component.
2022-02-01 11:10:09 +01:00
Sale Djenic 2ee91475e5 refactor(StatusAppNavBar): navigation bar displays buttons based on set model
`StatusAppNavBar` component is refactored in order to meet new changes we
have on the backend in the desktop app.
2022-02-01 11:10:09 +01:00
Alexandra Betouni b632c712c1 fix: Icon components had wrong color in sandbox app
Icon color in Icons page was broken as setting it
in main.qml was mistakenly removed. Set it back to
Theme.palette.primaryColor1

Closes #538
2022-02-01 08:45:46 +01:00
Pascal Precht f2c2106ce9 chore: cut 0.22.0 release 2022-01-31 09:15:38 +01:00
Noelia c5a605bf73 feat(StatusMemberListItem): Implement StatusMemberListItem (#539)
Create component StatusMemberListItem.

Add StatusMemberListItem component in sandbox\controls\ListItems for testing all its variants and demo app.

Add new properties in StatusListItem.

Reorganize StatusListItem.qml following Qt conventions.

Add badge in StatusSmartIndenticon component that allows configure a colored state.

Closes #515
2022-01-28 15:29:29 +01:00
Pascal Precht 4b9f59c845 chore: cut 0.21.0 release 2022-01-24 11:02:16 +01:00
Noelia 626695da25 feat(StatusQ.Controls): Introduce StatusPasswordStrengthIndicator
Create a password strength indicator component with the corresponding variation.

Create a base StatusProgressBar component.

Add new miscColor12.

Closes #528
2022-01-24 10:59:33 +01:00
Khushboo Mehta ea9556948b feat(StatusMessage): Introducing a new StatusQ Component for Chat Messages
The below mentioned features have been implemented in this component
1. Profile Picture of sender
2. Sender details - name, secondaryName, chatID
3. Text content
4. Image Content
5. Sticker Content
6. Audio Content
7. Reply Component with all the details for the message beinf replied to
8. Pinned component for Pinned message
9. Edit Component to edit the message
10. Loades to load the below -
    a. Link content loader
    b. transaction content
    c. invitation bubble
    d. footer - in this case to show emoji reactions to a message
    e. quick actions loader to show the related quick actions
2022-01-21 11:41:58 +01:00
Alexandra Betouni 0056df517d refactor: refactored/cleaned up sandbox app
Grouped QML files by pages, controls and demo app
related stuff
2022-01-19 16:22:52 +01:00
Alexandra Betouni 55901cf0a3 fix(build): broken MacOS build (#533)
moved DESTDIR in sandbox.pro above
copydata command as it was breaking
the build process on MacOS
2022-01-19 00:45:21 +02:00
Pascal Precht 76eac6fb72 chore: cut 0.20.0 release 2022-01-17 13:53:26 +01:00
Noelia 35d12f444d feat(StatusBanner): introduce type variants for different banner styles
* feat(sandbox/controls): Added StatusBanner component in controls view

In order to test StatusBanner.qml ui component it has been added into the Sandbox app as another Control.

* chore(sandbox/controls): Refactor `StatusBanner' component

Create enum to allow selecting StatusBanner type (`Info`, `Danger`, `Success`, `Warning`).

Add new success color with some opacity in ThemePalette.

* chore(Controls/StatusBanner): Use states instead of function

To have a cleaner code, it has been added states to manage type property changes.

* chore(Controls/StatusBanner): Remove unnecessary stuff

Remove unnecessary name property.
Remove successColor3 property.
2022-01-14 20:18:57 +01:00
Boris Melnik 14ab4ce52d fix(build): Windows build 2022-01-14 16:24:19 +01:00
Noelia c56dcd9eb4 Created new UI component StatusBanner and added into StatusQ/Controls 2022-01-12 09:37:17 +01:00
Khushboo Mehta 5a416aa1c9 fix(StatusBaseInput): Corrects allignment of the placeholder text in the StatusBaseInput. 2021-12-03 13:54:20 +01:00
Pascal Precht 2f8f5f423b chore: cut 0.19.0 release 2021-12-03 12:55:31 +01:00
Khushboo Mehta ab6bdf54c0 fix(StatusChatListItem): This change fixes the issue of the chat list items getting a highlight even when they are not really hovered
The issue is caused by the fact that the MouseArea returns containsMouse as true even when the item is not hovered.
The issue is reproduced when the model changes dynamically in the StatusChatList, thus causing the StatusChatListItem to be recreated and
this is when the containsMouse remains true even though the item is not hovered.
I see a bunch of issues in the QT bug list with regards to the containsMouse property but are still open.
A solution to this is to use HoverHandler which is a more reliable way getting hovered events for an item.
2021-12-03 12:32:24 +01:00
Pascal Precht 2336b6aab1 feat(StatusModal): introduce hasCloseButton property
This property can be used to hide the close button, as there are some
modals that shouldn't allow users to "x" modals away.
2021-12-01 10:21:51 +01:00
Pascal Precht 9a400ea45c chore: cut 0.18.0 release 2021-11-30 14:11:25 +01:00
Pascal Precht b7883e8298 fix(StatusListItem): ensure title is elided 2021-11-30 14:09:27 +01:00
Khushboo Mehta 8d2121ade6 fix(StatusImageWithTitle): Fix position of the edit title button 2021-11-30 13:58:27 +01:00
Khushboo Mehta f82ce8b732 feat(StatusListItem): Expose the Aside text so that it can be modified from the outside 2021-11-30 13:58:27 +01:00
Khushboo Mehta 419b738456 fix(StatusAppNavBar): Fixed position of profile button on the NavBar 2021-11-23 10:24:21 +01:00
Pascal Precht eed0b83a2d chore: cut 0.17.1 release 2021-11-19 14:50:44 +01:00
Anthony Laibe db0244365f fix(StatusAccountSelector): Adapt ui to data model changed 2021-11-19 14:50:00 +01:00
Khushboo Mehta 2040d0f857 fix(StatusAssetSelector): Fixed error of crypto balance not updated correctly
Also added error handling in case in case that crypto symbol image is not available
Added a way to display the balance in currently selected currency on the widget
To do this the consumer of this widget needs to implement "getCurrencyBalanceString" based on the currently selected currency

fixes #4079
2021-11-16 16:08:52 +01:00
Pascal Precht 9fa1592aaa chore: cut 0.17.0 release 2021-11-10 09:52:29 +01:00
Khushboo Mehta 0c715b1717 fix(StatusListItem): This solves the issue of channel list overlpaing when a category is collapsed.
The issue is not reproducible a 100% of time. In order to solve this bug, we have turned on the preventStealing flag for the mousseArea.
Checked for any sideimpacts but didnt find any.
Tried several times and this change seems to solve the bug. Feel free to repoen if you are still able to reproduce this behaviour.

fixes #4047
2021-11-09 10:43:41 +01:00
Jonathan Rainville ce8d3231be fix(StatusAccountSelector): adapt AccountSelector to new model (#482) 2021-11-05 14:08:31 -04:00
Pascal Precht e23dc533bd fix(StatusExpandibleItem): add missing hover indicator in Secondary type
Fixes #478
2021-11-04 14:55:46 +01:00
Anastasiya S fecfb2a7e9 fix(StatusSearchPopup): disable enter and return keys to avoid UI breakage 2021-11-04 14:54:00 +01:00
10289 changed files with 43473 additions and 2691 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/
+158
View File
@@ -1,3 +1,161 @@
<a name=""></a>
## 0.25.0 (2022-03-07)
#### Bug Fixes
* **@StatusListItem:** fix left padding ([f574e390](f574e390))
* **StatusListItem:** add propagateTitleClicks property to StatusListItem ([8495fae8](8495fae8))
* **StatusQ.Popups:** removed overlay setting (#557) ([665141f8](665141f8))
* **StatusTagSelector:** Updates and fixes in the component ([07a5dc09](07a5dc09))
* **build:** fix linux build ([9d06aae1](9d06aae1), closes [#413](413))
* **sandbox:** Fix results popup component position ([cdf51fef](cdf51fef))
#### Features
* **@StatusListItem:** add option for tags ([381150a7](381150a7))
* **StatusChatList:** Highlight chat item at creation time ([9e6fbe95](9e6fbe95))
* **StatusChatListItem:** enable assigning emoji to chat item ([5fac8774](5fac8774))
* **StatusContactVerificationIcons:** Create new row control that includes mutual connect and trust indicator icons (#559) ([c0f825c6](c0f825c6), closes [#542](542))
* **StatusQ:** Moving docs outside sandbox ([825999b1](825999b1))
* **StatusQ.Core:** add new arrow-left icon ([e9f20be1](e9f20be1))
* **StatusSmartIdenticon:** Add support for color rings in StatusSmartIdenticon (#553) ([3b86d13a](3b86d13a), closes [#517](517))
#### Breaking Changes
* **StatusContactVerificationIcons:** Create new row control that includes mutual connect and trust indicator icons (#559) ([c0f825c6](c0f825c6), closes [#542](542))
<a name=""></a>
## 0.24.0 (2022-02-14)
#### Features
* **StatusListItem:** add highlighted property ([5780f183](5780f183))
* **StatusQ.Components:** Adding StatusWizardSteper component ([b7d6554b](b7d6554b), closes [#522](522))
<a name=""></a>
## Version 0.23.0 (2022-02-08)
#### Bug Fixes
* Icon components had wrong color in sandbox app ([b632c712](b632c712), closes [#538](538))
* **StatusChatList:** unexisting property name for chat item fixed ([c2e07517](c2e07517))
#### Features
* **StatusQ.Components:**
* Adding StatusToastMessage ([7b290ddd](7b290ddd), closes [#521](521))
* Adding StatusTagSelector component ([094dee49](094dee49), closes [#526](526))
<a name=""></a>
## Version 0.22.0 (2022-01-31)
#### Features
* **StatusMemberListItem:** Implement `StatusMemberListItem` (#539) ([c5a605bf](c5a605bf), closes [#515](515))
<a name=""></a>
## Version 0.21.0 (2022-01-24)
#### Bug Fixes
* **build:** broken MacOS build (#533) ([55901cf0](55901cf0))
#### Features
* **StatusMessage:** Introducing a new StatusQ Component for Chat Messages ([ea955694](ea955694))
* **StatusQ.Controls:** Introduce `StatusPasswordStrengthIndicator` ([626695da](626695da), closes [#528](528))
<a name=""></a>
## Version 0.20.0 (2022-01-17)
#### Features
* **StatusBanner:** introduce type variants for different banner styles ([35d12f44](35d12f44))
#### Bug Fixes
* **StatusBaseInput:** Corrects allignment of the placeholder text in the StatusBaseInput. ([5a416aa1](5a416aa1))
* **build:** Windows build ([14ab4ce5](14ab4ce5))
<a name=""></a>
## Version 0.19.0 (2021-12-03)
#### Bug Fixes
* **StatusChatListItem:** This change fixes the issue of the chat list items getting a highlight even when they are not really hovered ([ab6bdf54](ab6bdf54))
#### Features
* **StatusModal:** introduce `hasCloseButton` property ([2336b6aa](2336b6aa))
<a name=""></a>
## Version 0.18.0 (2021-11-30)
#### Bug Fixes
* **StatusAppNavBar:** Fixed position of profile button on the NavBar ([419b7384](419b7384))
* **StatusImageWithTitle:** Fix position of the edit title button ([8d2121ad](8d2121ad))
* **StatusListItem:** ensure title is elided ([b7883e82](b7883e82))
#### Features
* **StatusListItem:** Expose the Aside text so that it can be modified from the outside ([f82ce8b7](f82ce8b7))
<a name=""></a>
## Version 0.17.1 (2021-11-19)
#### Bug Fixes
* **StatusAccountSelector:** Adapt ui to data model changed ([db024436](db024436))
* **StatusAssetSelector:** Fixed error of crypto balance not updated correctly ([2040d0f8](2040d0f8))
<a name=""></a>
## Version 0.17.0 (2021-11-10)
#### Features
* **StatusBaseButton:** introduce `Tiny` size ([dee9f437](dee9f437))
* **StatusQ.Controls.Validators:** introduce `StatusUrlValidator` ([a9155865](a9155865))
#### Bug Fixes
* **StatusAccountSelector:** adapt AccountSelector to new model (#482) ([ce8d3231](ce8d3231))
* **StatusExpandibleItem:** add missing hover indicator in `Secondary` type ([e23dc533](e23dc533), closes [#478](478))
* **StatusInput:** ensure validator messages are rendered when validators return boolean values ([f82cd7f5](f82cd7f5))
* **StatusListItem:** This solves the issue of channel list overlpaing when a category is collapsed. ([0c715b17](0c715b17))
* **StatusSearchPopup:** disable enter and return keys to avoid UI breakage ([fecfb2a7](fecfb2a7))
* **StatusSlider:** slider background and handle should not depend on root's height ([31cfc883](31cfc883))
<a name=""></a>
## Version 0.16.0 (2021-11-01)
+5
View File
@@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.19)
project(StatusQ)
add_subdirectory(tests)
Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

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: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

+19
View File
@@ -0,0 +1,19 @@
/*!
\page statusq-index.html
\title StatusQ
\brief A components library for Status desktop client.
StatusQ provides a collection of components....
StatusQ - Components and Interfaces
\list
\li \l{StatusQ Components}{Components}
\li \l{StatusQ Controls}{Controls}
\li \l{StatusQ Core}{Core}
\li \l{StatusQ Layout}{Layout}
\li \l{StatusQ Platform}{Platform}
\li \l{StatusQ Popups}{Popups}
\endlist
*/
+43
View File
@@ -0,0 +1,43 @@
/*!
\qmlmodule StatusQ.Components 0.1
\title StatusQ Components
\brief Basic set of Components StatusQ components
This is a listing of all Components components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusAddress}
\li \l{StatusBadge}
\li \l{StatusChatInfoToolBar}
\li \l{StatusChatList}
\li \l{StatusChatListItem}
\li \l{StatusImageSettings}
\li \l{StatusChatListCategory}
\li \l{StatusChatListCategoryItem}
\li \l{StatusChatListAndCategories}
\li \l{StatusChatToolBar}
\li \l{StatusContactRequestsIndicatorListItem}
\li \l{StatusDescriptionListItem}
\li \l{StatusLetterIdenticon}
\li \l{StatusListItem}
\li \l{StatusListPicker}
\li \l{StatusListSectionHeadline}
\li \l{StatusLoadingIndicator}
\li \l{StatusMemberListItem}
\li \l{StatusNavigationListItem}
\li \l{StatusNavigationPanelHeadline}
\li \l{StatusRoundIcon}
\li \l{StatusRoundedImage}
\li \l{StatusMacWindowButtons}
\li \l{StatusListItemBadge}
\li \l{StatusExpandableItem}
\li \l{StatusSmartIdenticon}
\li \l{StatusMessage}
\li \l{StatusMessageDetails}
\li \l{StatusTagSelector}
\li \l{StatusToastMessage}
\li \l{StatusWizardStepper}
\endlist
*/
+49
View File
@@ -0,0 +1,49 @@
/*!
\qmlmodule StatusQ.Controls 0.1
\title StatusQ Controls
\brief Basic set of Controls StatusQ components
This is a listing of all Controls components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusAccountSelector}
\li \l{StatusAssetSelector}
\li \l{StatusBanner}
\li \l{StatusChatCommandButton}
\li \l{StatusChatInfoButton}
\li \l{StatusChatListCategoryItemButton}
\li \l{StatusColorSelector}
\li \l{StatusIconTabButton}
\li \l{StatusNavBarTabButton}
\li \l{StatusTabBarIconButton}
\li \l{StatusToolTip}
\li \l{StatusBaseButton}
\li \l{StatusButton}
\li \l{StatusFlatButton}
\li \l{StatusRoundButton}
\li \l{StatusFlatRoundButton}
\li \l{StatusSwitch}
\li \l{StatusRadioButton}
\li \l{StatusCheckBox}
\li \l{StatusSlider}
\li \l{StatusSelect}
\li \l{StatusBaseInput}
\li \l{StatusIdenticonRing}
\li \l{StatusInput}
\li \l{StatusItemPicker}
\li \l{StatusPickerButton}
\li \l{StatusPinInput}
\li \l{StatusProgressBar}
\li \l{StatusPasswordStrengthIndicator}
\li \l{StatusSwitchTabButton}
\li \l{StatusSwitchTabBar}
\li \l{StatusSelectableText}
\li \l{StatusWalletColorButton}
\li \l{StatusWalletColorSelect}
\li \l{StatusRegularExpressionValidator}
\li \l{StatusIntValidator}
\li \l{StatusSeedPhraseInput}
\endlist
*/
+23
View File
@@ -0,0 +1,23 @@
/*!
\qmlmodule StatusQ.Core 0.1
\title StatusQ Core
\brief Basic set of Core StatusQ components
This is a listing of all Core components. These
files are available for general import and they are based off the \l{https://doc.qt.io/qt-5/qtquick-qmlmodule.html}{Qt
Quick Primitives} and \l{https://doc.qt.io/archives/qt-5.11/qtquick-controls2-qmlmodule.html}{Qt Quick Controls 2}.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusAppNavBarFilterModel}
\li \l{StatusBaseText}
\li \l{StatusIcon}
\li \l{StatusIconBackgroundSettings}
\li \l{StatusIconSettings}
\li \l{StatusIdenticonRingSettings}
\li \l{StatusImageSettings}
\li \l{StatusModalHeaderSettings}
\li \l{StatusTooltipSettings}
\endlist
*/
+16
View File
@@ -0,0 +1,16 @@
/*!
\qmlmodule StatusQ.Layout 0.1
\title StatusQ Layout
\brief Basic set of Layout StatusQ components
This is a listing of all Layout components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusAppLayout}
\li \l{StatusAppNavBar}
\li \l{StatusAppTwoPanelLayout}
\li \l{StatusAppThreePanelLayout}
\endlist
*/
+15
View File
@@ -0,0 +1,15 @@
/*!
\qmlmodule StatusQ.Platform 0.1
\title StatusQ Platform
\brief Basic set of Platform StatusQ components
This is a listing of all Platform components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusMacTrafficLights}
\li \l{StatusMacNotification}
\li \l{StatusWindowsTitleBar}
\endlist
*/
+22
View File
@@ -0,0 +1,22 @@
/*!
\qmlmodule StatusQ.Popups 0.1
\title StatusQ Popups
\brief Basic set of Popups StatusQ components
This is a listing of all Popups components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusMenuSeparator}
\li \l{StatusPopupMenu}
\li \l{StatusMenuItem}
\li \l{StatusMenuItemDelegate}
\li \l{StatusModal}
\li \l{StatusSearchPopup}
\li \l{StatusModalDivider}
\li \l{StatusSearchPopupMenuItem}
\li \l{StatusSearchLocationMenu}
\li \l{StatusSpellcheckingMenuItems}
\endlist
*/
+36
View File
@@ -0,0 +1,36 @@
project = StatusQ
version = 0.1
description = StatusQ Project
url = https://github.com/status-im/StatusQ
#These are set implictly by qdoc as well, but only with these the module header can be found
includepaths = -I . \
-I $PWD/../src/StatusQ
imagedirs = src/images
sourcedirs += src \
$PWD/../src/StatusQ/Components \
$PWD/../src/StatusQ/Controls \
$PWD/../src/StatusQ/Core \
$PWD/../src/StatusQ/Layout \
$PWD/../src/StatusQ/Platform \
$PWD/../src/StatusQ/Popups \
sources.fileextensions = "*.cpp *.qdoc *.qml"
depends += qtcore \
qtquick \
qtqml \
qtgui \
qtdoc \
qtquickcontrols2
navigation.homepage = "StatusQ"
outputdir = $PWD/html
outputformats = HTML
HTML.stylesheets = style.css
HTML.headerstyles = "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\"/>\n"
HTML.postheader = "<p class=\"header\"><small>StatusQ - A Components selection for Status dekstop client. </p></small></p><hr/>"
HTML.footer = "<hr/><div class=\"footer\"><p><acronym title=\"Copyright\">&copy;</acronym> 2022 Status. All rights reserved. <a href=\"https://status.im\" target=\"_blank\"><small>status.im</a></small></p></div>"
+41
View File
@@ -0,0 +1,41 @@
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;
}
+99 -765
View File
@@ -9,6 +9,9 @@ import StatusQ.Layout 0.1
import StatusQ.Popups 0.1
import StatusQ.Platform 0.1
import "demoapp"
import "demoapp/data" 1.0
Rectangle {
id: demoApp
height: 602
@@ -18,6 +21,31 @@ Rectangle {
property string titleStyle: "osx"
QtObject {
id: appSectionType
readonly property int chat: 0
readonly property int community: 1
readonly property int wallet: 2
readonly property int browser: 3
readonly property int nodeManagement: 4
readonly property int profileSettings: 5
readonly property int apiDocumentation: 100
readonly property int demoApp: 101
}
function setActiveItem(sectionId) {
for (var i = 0; i < Models.demoAppSectionsModel.count; i++) {
let item = Models.demoAppSectionsModel.get(i)
if (item.sectionId !== sectionId)
{
Models.demoAppSectionsModel.setProperty(i, "active", false)
continue
}
Models.demoAppSectionsModel.setProperty(i, "active", true);
}
}
StatusMacTrafficLights {
anchors.left: parent.left
anchors.top: parent.top
@@ -48,32 +76,74 @@ Rectangle {
id: navBar
navBarChatButton: StatusNavBarTabButton {
icon.name: "chat"
tooltip.text: "Chat"
checked: appView.sourceComponent == statusAppChatView
onClicked: {
appView.sourceComponent = statusAppChatView
}
communityTypeRole: "sectionType"
communityTypeValue: appSectionType.community
sectionModel: Models.demoAppSectionsModel
property bool communityAdded: false
onAboutToUpdateFilteredRegularModel: {
communityAdded = false
}
navBarCommunityTabButtons.model: ListModel {
ListElement {
name: "Status Community"
tooltipText: "Status Community"
}
filterRegularItem: function(item) {
if(item.sectionType === appSectionType.community)
if(communityAdded)
return false
else
communityAdded = true
return true
}
navBarCommunityTabButtons.delegate: StatusNavBarTabButton {
id: communityBtn
filterCommunityItem: function(item) {
return item.sectionType === appSectionType.community
}
regularNavBarButton: StatusNavBarTabButton {
anchors.horizontalCenter: parent.horizontalCenter
name: model.name
tooltip.text: model.tooltipText
icon.color: Theme.palette.miscColor6
icon.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
checked: appView.sourceComponent == statusAppCommunityView
name: model.icon.length > 0? "" : model.name
icon.name: model.icon
icon.source: model.image
tooltip.text: model.name
autoExclusive: true
checked: model.active
badge.value: model.notificationsCount
badge.visible: model.hasNotification
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
onClicked: {
appView.sourceComponent = statusAppCommunityView
if(model.sectionType === appSectionType.chat)
{
appView.sourceComponent = statusAppChatView
demoApp.setActiveItem(model.sectionId)
}
else if(model.sectionType === appSectionType.profileSettings)
{
appView.sourceComponent = statusAppProfileSettingsView
demoApp.setActiveItem(model.sectionId)
}
}
}
communityNavBarButton: StatusNavBarTabButton {
anchors.horizontalCenter: parent.horizontalCenter
name: model.icon.length > 0? "" : model.name
icon.name: model.icon
icon.source: model.image
tooltip.text: model.name
autoExclusive: true
checked: model.active
badge.value: model.notificationsCount
badge.visible: model.hasNotification
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
onClicked: {
if(model.sectionType === appSectionType.community)
{
appView.sourceComponent = statusAppCommunityView
demoApp.setActiveItem(model.sectionId)
}
}
popupMenu: StatusPopupMenu {
@@ -104,39 +174,7 @@ Rectangle {
type: StatusMenuItem.Type.Danger
}
}
}
navBarTabButtons: [
StatusNavBarTabButton {
icon.name: "wallet"
tooltip.text: "Wallet"
},
StatusNavBarTabButton {
icon.name: "bigger/browser"
tooltip.text: "Browser"
},
StatusNavBarTabButton {
icon.name: "bigger/status-update"
tooltip.text: "Timeline"
},
StatusNavBarTabButton {
id: profileNavButton
icon.name: "bigger/settings"
badge.visible: true
badge.anchors.rightMargin: 4
badge.anchors.topMargin: 5
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusAppNavBar.backgroundColor
badge.border.width: 2
tooltip.text: "Profile"
checked: appView.sourceComponent == statusAppProfileSettingsView
onClicked: {
appView.sourceComponent = statusAppProfileSettingsView
}
}
]
}
appView: Loader {
@@ -148,735 +186,31 @@ Rectangle {
Component {
id: statusAppChatView
StatusAppTwoPanelLayout {
leftPanel: Item {
anchors.fill: parent
StatusNavigationPanelHeadline {
id: headline
anchors.top: parent.top
anchors.topMargin: 16
anchors.horizontalCenter: parent.horizontalCenter
text: "Chat"
}
Item {
id: searchInputWrapper
anchors.top: headline.bottom
anchors.topMargin: 16
width: parent.width
height: searchInput.height
StatusBaseInput {
id: searchInput
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: actionButton.left
anchors.leftMargin: 16
anchors.rightMargin: 16
height: 36
topPadding: 8
bottomPadding: 0
placeholderText: "Search"
icon.name: "search"
}
StatusRoundButton {
id: actionButton
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 8
width: 32
height: 32
type: StatusRoundButton.Type.Secondary
icon.name: "add"
state: "default"
onClicked: chatContextMenu.popup(actionButton.width-chatContextMenu.width, actionButton.height + 4)
states: [
State {
name: "default"
PropertyChanges {
target: actionButton
icon.rotation: 0
highlighted: false
}
},
State {
name: "pressed"
PropertyChanges {
target: actionButton
icon.rotation: 45
highlighted: true
}
}
]
transitions: [
Transition {
from: "default"
to: "pressed"
RotationAnimation {
duration: 150
direction: RotationAnimation.Clockwise
easing.type: Easing.InCubic
}
},
Transition {
from: "pressed"
to: "default"
RotationAnimation {
duration: 150
direction: RotationAnimation.Counterclockwise
easing.type: Easing.OutCubic
}
}
]
StatusPopupMenu {
id: chatContextMenu
onOpened: {
actionButton.state = "pressed"
}
onClosed: {
actionButton.state = "default"
}
StatusMenuItem {
text: "Start new chat"
icon.name: "private-chat"
}
StatusMenuItem {
text: "Start group chat"
icon.name: "group-chat"
}
StatusMenuItem {
text: "Join public chat"
icon.name: "public-chat"
}
StatusMenuItem {
text: "Communities"
icon.name: "communities"
}
}
}
}
Column {
anchors.top: searchInputWrapper.bottom
anchors.topMargin: 16
width: parent.width
spacing: 8
StatusContactRequestsIndicatorListItem {
anchors.horizontalCenter: parent.horizontalCenter
title: "Contact requests"
requestsCount: 3
sensor.onClicked: demoContactRequestsModal.open()
}
StatusChatList {
anchors.horizontalCenter: parent.horizontalCenter
chatListItems.model: models.demoChatListItems
selectedChatId: "0"
onChatItemSelected: selectedChatId = id
onChatItemUnmuted: {
for (var i = 0; i < models.demoChatListItems.count; i++) {
let item = models.demoChatListItems.get(i);
if (item.chatId === id) {
models.demoChatListItems.setProperty(i, "muted", false)
}
}
}
popupMenu: StatusPopupMenu {
property string chatId
openHandler: function (id) {
chatId = id
}
StatusMenuItem {
text: "View Profile"
icon.name: "group-chat"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Mute chat"
icon.name: "notification"
}
StatusMenuItem {
text: "Mark as Read"
icon.name: "checkmark-circle"
}
StatusMenuItem {
text: "Clear history"
icon.name: "close-circle"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Delete chat"
icon.name: "delete"
type: StatusMenuItem.Type.Danger
}
}
}
}
}
rightPanel: Item {
anchors.fill: parent
StatusChatToolBar {
anchors.top: parent.top
width: parent.width
chatInfoButton.title: "Amazing Funny Squirrel"
chatInfoButton.subTitle: "Contact"
chatInfoButton.icon.color: Theme.palette.miscColor7
chatInfoButton.type: StatusChatInfoButton.Type.OneToOneChat
chatInfoButton.pinnedMessagesCount: 1
searchButton.visible: false
membersButton.visible: false
notificationCount: 1
onNotificationButtonClicked: notificationCount = 0
popupMenu: StatusPopupMenu {
id: contextMenu
StatusMenuItem {
text: "Mute Chat"
icon.name: "notification"
}
StatusMenuItem {
text: "Mark as Read"
icon.name: "checkmark-circle"
}
StatusMenuItem {
text: "Clear History"
icon.name: "close-circle"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Leave Chat"
icon.name: "arrow-right"
icon.width: 14
iconRotation: 180
type: StatusMenuItem.Type.Danger
}
}
}
}
}
StatusAppChatView { }
}
Component {
id: statusAppCommunityView
StatusAppThreePanelLayout {
id: root
handle: Rectangle {
implicitWidth: 5
color: SplitHandle.pressed ? Theme.palette.baseColor2
: (SplitHandle.hovered ? Qt.darker(Theme.palette.baseColor5, 1.1) : "transparent")
}
leftPanel: Item {
id: leftPanel
StatusChatInfoToolBar {
id: statusChatInfoToolBar
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
chatInfoButton.title: "CryptoKitties"
chatInfoButton.subTitle: "128 Members"
chatInfoButton.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
chatInfoButton.icon.color: Theme.palette.miscColor6
chatInfoButton.onClicked: demoCommunityDetailModal.open()
popupMenu: StatusPopupMenu {
StatusMenuItem {
text: "Create channel"
icon.name: "channel"
}
StatusMenuItem {
text: "Create category"
icon.name: "channel-category"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Invite people"
icon.name: "share-ios"
}
}
}
ScrollView {
id: scrollView
anchors.top: statusChatInfoToolBar.bottom
anchors.topMargin: 8
anchors.bottom: parent.bottom
width: leftPanel.width
contentHeight: communityCategories.height
clip: true
StatusChatListAndCategories {
id: communityCategories
width: leftPanel.width
height: implicitHeight > (leftPanel.height - 64) ? implicitHeight + 8 : leftPanel.height - 64
draggableItems: true
draggableCategories: false
chatList.model: models.demoCommunityChatListItems
categoryList.model: models.demoCommunityCategoryItems
showCategoryActionButtons: true
onChatItemSelected: selectedChatId = id
categoryPopupMenu: StatusPopupMenu {
property string categoryId
openHandler: function (id) {
categoryId = id
}
StatusMenuItem {
text: "Mute Category"
icon.name: "notification"
}
StatusMenuItem {
text: "Mark as Read"
icon.name: "checkmark-circle"
}
StatusMenuItem {
text: "Edit Category"
icon.name: "edit"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Delete Category"
icon.name: "delete"
type: StatusMenuItem.Type.Danger
}
}
chatListPopupMenu: StatusPopupMenu {
property string chatId
StatusMenuItem {
text: "Mute chat"
icon.name: "notification"
}
StatusMenuItem {
text: "Mark as Read"
icon.name: "checkmark-circle"
}
StatusMenuItem {
text: "Clear history"
icon.name: "close-circle"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Delete chat"
icon.name: "delete"
type: StatusMenuItem.Type.Danger
}
}
popupMenu: StatusPopupMenu {
StatusMenuItem {
text: "Create channel"
icon.name: "channel"
}
StatusMenuItem {
text: "Create category"
icon.name: "channel-category"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Invite people"
icon.name: "share-ios"
}
}
}
}
}
centerPanel: Item {
StatusChatToolBar {
id: statusChatToolBar
anchors.top: parent.top
width: parent.width
chatInfoButton.title: "general"
chatInfoButton.subTitle: "Community Chat"
chatInfoButton.icon.color: Theme.palette.miscColor6
chatInfoButton.type: StatusChatInfoButton.Type.CommunityChat
onSearchButtonClicked: {
searchButton.highlighted = !searchButton.highlighted;
searchPopup.setSearchSelection(demoCommunityDetailModal.header.title,
"",
demoCommunityDetailModal.header.image.source);
searchPopup.open();
}
membersButton.onClicked: membersButton.highlighted = !membersButton.highlighted
onMembersButtonClicked: {
root.showRightPanel = !root.showRightPanel;
}
}
StatusSearchPopup {
id: searchPopup
searchOptionsPopupMenu: searchPopupMenu
onAboutToHide: {
if (searchPopupMenu.visible) {
searchPopupMenu.close();
}
//clear menu
for (var i = 2; i < searchPopupMenu.count; i++) {
searchPopupMenu.removeItem(searchPopupMenu.takeItem(i));
}
}
onClosed: {
statusChatToolBar.searchButton.highlighted = false
searchPopupMenu.dismiss();
}
onSearchTextChanged: {
if (searchPopup.searchText !== "") {
searchPopup.loading = true;
searchModelSimTimer.start();
} else {
searchPopup.searchResults = [];
searchModelSimTimer.stop();
}
}
Timer {
id: searchModelSimTimer
interval: 500
onTriggered: {
if (searchPopup.searchText.startsWith("c")) {
searchPopup.searchResults = models.searchResultsA;
} else {
searchPopup.searchResults = models.searchResultsB;
}
searchPopup.loading = false;
}
}
}
StatusSearchLocationMenu {
id: searchPopupMenu
searchPopup: searchPopup
locationModel: models.optionsModel
}
}
rightPanel: Item {
id: rightPanel
StatusBaseText {
id: titleText
anchors.top: parent.top
anchors.topMargin:16
anchors.left: parent.left
anchors.leftMargin: 16
opacity: (rightPanel.width > 50) ? 1.0 : 0.0
visible: (opacity > 0.1)
font.pixelSize: 15
text: qsTr("Members")
}
ListView {
anchors.top: titleText.bottom
anchors.topMargin: 16
anchors.left: parent.left
anchors.leftMargin: 8
anchors.right: parent.right
anchors.rightMargin: 8
anchors.bottom: parent.bottom
anchors.bottomMargin: 16
boundsBehavior: Flickable.StopAtBounds
model: ["John", "Nick", "Maria", "Mike"]
delegate: Row {
width: parent.width
height: 30
spacing: 8
Rectangle {
width: 24
height: 24
radius: width/2
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 255)
}
StatusBaseText {
height: parent.height
horizontalAlignment: Text.AlignHCenter
opacity: (rightPanel.width > 50) ? 1.0 : 0.0
visible: (opacity > 0.1)
font.pixelSize: 15
color: Theme.palette.directColor1
text: modelData
}
}
}
StatusAppCommunityView {
communityDetailModalTitle: demoCommunityDetailModal.header.title
communityDetailModalImage: demoCommunityDetailModal.header.image.source
onChatInfoButtonClicked: {
demoCommunityDetailModal.open();
}
}
}
Component {
id: statusAppProfileSettingsView
StatusAppTwoPanelLayout {
leftPanel: Item {
anchors.fill: parent
StatusNavigationPanelHeadline {
id: profileHeadline
anchors.top: parent.top
anchors.topMargin: 16
anchors.horizontalCenter: parent.horizontalCenter
text: "Profile"
}
ScrollView {
anchors.top: profileHeadline.bottom
anchors.topMargin: 16
anchors.bottom: parent.bottom
width: parent.width
contentHeight: profileMenuItems.height + 8
contentWidth: parent.width
clip: true
Column {
id: profileMenuItems
anchors.horizontalCenter: parent.horizontalCenter
spacing: 4
Repeater {
model: models.demoProfileGeneralMenuItems
delegate: StatusNavigationListItem {
title: model.title
icon.name: model.icon
}
}
StatusListSectionHeadline { text: "Settings" }
Repeater {
model: models.demoProfileSettingsMenuItems
delegate: StatusNavigationListItem {
title: model.title
icon.name: model.icon
}
}
Item {
id: invisibleSeparator
height: 16
width: parent.width
}
Repeater {
model: models.demoProfileOtherMenuItems
delegate: StatusNavigationListItem {
title: model.title
icon.name: model.icon
}
}
}
}
}
rightPanel: Item {
anchors.fill: parent
}
}
StatusAppProfileSettingsView { }
}
StatusModal {
DemoContactRequestsModal {
id: demoContactRequestsModal
anchors.centerIn: parent
header.title: "Contact Requests"
headerActionButton: StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
width: 32
height: 32
icon.width: 20
icon.height: 20
icon.name: "notification"
}
contentItem: StatusBaseText {
anchors.centerIn: parent
text: "Contact request will be shown here"
font.pixelSize: 15
color: Theme.palette.directColor1
}
rightButtons: [
StatusButton {
text: "Decline all"
type: StatusBaseButton.Type.Danger
onClicked: demoContactRequestsModal.close()
},
StatusButton {
text: "Accept all"
onClicked: demoContactRequestsModal.close()
}
]
}
StatusModal {
DemoCommunityDetailModal {
id: demoCommunityDetailModal
anchors.centerIn: parent
header.title: "Cryptokitties"
header.subTitle: "Public Community"
header.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
contentItem: Column {
width: demoCommunityDetailModal.width
StatusModalDivider {
bottomPadding: 8
}
StatusBaseText {
text: "A community of cat lovers, meow!"
verticalAlignment: Text.AlignVCenter
font.pixelSize: 15
height: 46
color: Theme.palette.directColor1
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.rightMargin: 16
}
StatusModalDivider {
topPadding: 8
bottomPadding: 8
}
StatusDescriptionListItem {
title: "Share community"
subTitle: "https://join.status.im/u/0x04...45f19"
tooltip.text: "Copy to clipboard"
icon.name: "copy"
iconButton.onClicked: tooltip.visible = !tooltip.visible
width: parent.width
}
StatusModalDivider {
topPadding: 8
bottomPadding: 8
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Members"
icon.name: "group-chat"
label: "184"
components: [
StatusIcon {
icon: "chevron-down"
rotation: 270
color: Theme.palette.baseColor1
}
]
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Notifications"
icon.name: "notification"
components: [
StatusSwitch {}
]
}
StatusModalDivider {
topPadding: 8
bottomPadding: 8
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Edit community"
icon.name: "edit"
type: StatusListItem.Type.Secondary
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Transfer ownership"
icon.name: "exchange"
type: StatusListItem.Type.Secondary
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Leave community"
icon.name: "arrow-right"
icon.rotation: 180
type: StatusListItem.Type.Secondary
}
}
}
Models {
id: models
}
}
-295
View File
@@ -1,295 +0,0 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Layout 0.1
Column {
spacing: 5
StatusChatToolBar {
chatInfoButton.title: "Some contact"
chatInfoButton.subTitle: "Contact"
chatInfoButton.icon.color: Theme.palette.miscColor7
chatInfoButton.type: StatusChatInfoButton.Type.OneToOneChat
}
StatusChatToolBar {
chatInfoButton.title: "Some contact"
chatInfoButton.subTitle: "Contact"
chatInfoButton.icon.color: Theme.palette.miscColor7
chatInfoButton.type: StatusChatInfoButton.Type.PublicChat
chatInfoButton.pinnedMessagesCount: 1
chatInfoButton.muted: true
}
StatusChatToolBar {
chatInfoButton.title: "Some contact"
chatInfoButton.subTitle: "Contact"
chatInfoButton.icon.color: Theme.palette.miscColor7
chatInfoButton.type: StatusChatInfoButton.Type.OneToOneChat
chatInfoButton.pinnedMessagesCount: 1
notificationCount: 1
}
Row {
spacing: 5
Button {
id: btn
text: "Append"
onClicked: {
buttons.append({
name: "Test community",
tooltipText: "Test Community"
})
}
}
StatusAppNavBar {
navBarChatButton: StatusNavBarTabButton {
icon.name: "chat"
badge.value: 33
badge.visible: true
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
tooltip.text: "Chat"
}
}
StatusAppNavBar {
navBarChatButton: StatusNavBarTabButton {
icon.name: "chat"
badge.value: 33
badge.visible: true
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
tooltip.text: "Chat"
}
navBarCommunityTabButtons.model: ListModel {
id: buttons
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
}
navBarCommunityTabButtons.delegate: StatusNavBarTabButton {
name: model.name
tooltip.text: model.name
anchors.horizontalCenter: parent.horizontalCenter
}
navBarTabButtons: [
StatusNavBarTabButton {
icon.name: "wallet"
tooltip.text: "Wallet"
},
StatusNavBarTabButton {
icon.name: "browser"
tooltip.text: "Browser"
},
StatusNavBarTabButton {
icon.name: "status-update"
tooltip.text: "Timeline"
},
StatusNavBarTabButton {
icon.name: "profile"
badge.visible: true
badge.anchors.rightMargin: 4
badge.anchors.topMargin: 5
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
tooltip.text: "Profile"
}
]
}
StatusAppNavBar {
navBarChatButton: StatusNavBarTabButton {
icon.name: "chat"
badge.value: 33
badge.visible: true
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
tooltip.text: "Chat"
}
navBarCommunityTabButtons.model: ListModel {
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
}
navBarCommunityTabButtons.delegate: StatusNavBarTabButton {
name: model.name
tooltip.text: model.name
anchors.horizontalCenter: parent.horizontalCenter
}
navBarTabButtons: [
StatusNavBarTabButton {
icon.name: "wallet"
tooltip.text: "Wallet"
},
StatusNavBarTabButton {
icon.name: "browser"
tooltip.text: "Browser"
}
]
}
StatusAppNavBar {
navBarChatButton: StatusNavBarTabButton {
icon.name: "chat"
badge.value: 33
badge.visible: true
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
tooltip.text: "Chat"
}
navBarCommunityTabButtons.model: ListModel {
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
}
navBarCommunityTabButtons.delegate: StatusNavBarTabButton {
name: model.name
tooltip.text: model.name
anchors.horizontalCenter: parent.horizontalCenter
}
navBarTabButtons: [
StatusNavBarTabButton {
icon.name: "wallet"
tooltip.text: "Wallet"
},
StatusNavBarTabButton {
icon.name: "browser"
tooltip.text: "Browser"
},
StatusNavBarTabButton {
icon.name: "status-update"
tooltip.text: "Timeline"
},
StatusNavBarTabButton {
icon.name: "profile"
badge.visible: true
badge.anchors.rightMargin: 4
badge.anchors.topMargin: 5
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
tooltip.text: "Profile"
}
]
}
StatusAppNavBar {
id: test
navBarChatButton: StatusNavBarTabButton {
icon.name: "chat"
badge.value: 33
badge.visible: true
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
tooltip.text: "Chat"
}
navBarCommunityTabButtons.model: ListModel {
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
ListElement {
name: "Test community"
tooltipText: "Test Community"
}
}
navBarCommunityTabButtons.delegate: StatusNavBarTabButton {
name: model.name
tooltip.text: model.name
anchors.horizontalCenter: parent.horizontalCenter
}
navBarTabButtons: [
StatusNavBarTabButton {
icon.name: "wallet"
tooltip.text: "Wallet"
},
StatusNavBarTabButton {
icon.name: "browser"
tooltip.text: "Browser"
},
StatusNavBarTabButton {
icon.name: "status-update"
tooltip.text: "Timeline"
},
StatusNavBarTabButton {
icon.name: "profile"
badge.visible: true
badge.anchors.rightMargin: 4
badge.anchors.topMargin: 5
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
tooltip.text: "Profile"
}
]
}
}
}
-336
View File
@@ -1,336 +0,0 @@
import QtQuick 2.14
import StatusQ.Components 0.1
QtObject {
property var demoChatListItems: ListModel {
id: demoChatListItems
ListElement {
chatId: "0"
name: "#status"
chatType: StatusChatListItem.Type.PublicChat
muted: false
unreadMessagesCount: 0
mentionsCount: 0
color: "blue"
position: 0
}
ListElement {
chatId: "1"
name: "status-desktop"
chatType: StatusChatListItem.Type.PublicChat
muted: false
color: "red"
unreadMessagesCount: 1
mentionsCount: 1
position: 1
}
ListElement {
chatId: "2"
name: "Amazing Funny Squirrel"
chatType: StatusChatListItem.Type.OneToOneChat
muted: false
color: "green"
identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
unreadMessagesCount: 0
position: 2
}
ListElement {
chatId: "3"
name: "Black Ops"
chatType: StatusChatListItem.Type.GroupChat
muted: false
color: "purple"
unreadMessagesCount: 0
position: 3
}
ListElement {
chatId: "4"
name: "Spectacular Growing Otter"
chatType: StatusChatListItem.Type.OneToOneChat
muted: true
color: "Orange"
unreadMessagesCount: 0
position: 4
}
ListElement {
chatId: "5"
name: "channel-with-a-super-duper-long-name"
chatType: StatusChatListItem.Type.PublicChat
muted: false
color: "green"
unreadMessagesCount: 0
position: 5
}
}
property var demoCommunityChatListItems: ListModel {
id: demoCommunityChatListItems
ListElement {
chatId: "0"
name: "general"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
unreadMessagesCount: 0
color: "orange"
position: 0
}
ListElement {
chatId: "1"
name: "random"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
unreadMessagesCount: 0
color: "orange"
categoryId: "public"
position: 0
}
ListElement {
chatId: "2"
name: "watercooler"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
unreadMessagesCount: 0
color: "orange"
categoryId: "public"
position: 1
}
ListElement {
chatId: "3"
name: "language-design"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
unreadMessagesCount: 0
color: "orange"
categoryId: "dev"
position: 0
}
}
property var demoCommunityCategoryItems: ListModel {
id: demoCommunityCategoryItems
ListElement {
categoryId: "public"
name: "Public"
position: 0
}
ListElement {
categoryId: "dev"
name: "Development"
position: 1
}
}
property var demoProfileGeneralMenuItems: ListModel {
id: demoProfileGeneralMenuItems
ListElement {
title: "My Profile"
icon: "profile"
}
ListElement {
title: "Contacts"
icon: "contact"
}
ListElement {
title: "ENS Usernames"
icon: "username"
}
}
property var demoProfileSettingsMenuItems: ListModel {
id: demoProfileSettingsMenuItems
ListElement {
title: "Privacy & Security"
icon: "security"
}
ListElement {
title: "Appearance"
icon: "appearance"
}
ListElement {
title: "Browser"
icon: "browser"
}
ListElement {
title: "Sounds"
icon: "sound"
}
ListElement {
title: "Language"
icon: "language"
}
ListElement {
title: "Notifications"
icon: "notification"
}
ListElement {
title: "Sync settings"
icon: "mobile"
}
ListElement {
title: "Advanced"
icon: "settings"
}
}
property var demoProfileOtherMenuItems: ListModel {
id: demoProfileOtherMenuItems
ListElement {
title: "Need help?"
icon: "help"
}
ListElement {
title: "About"
icon: "info"
}
ListElement {
title: "Sign out & Quit"
icon: "logout"
}
}
//dummy search popup models
property var searchResultsA: ListModel {
ListElement { itemId: "i1"; titleId: "t1"; title: "@Flea"; sectionName: "Messages"; time: "18:55 AM"; content: "lorem ipsum <font color='#4360DF'>@Nick</font> dolor sit amet";
image: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg";
color: "orange";
badgeImage: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg";
badgePrimaryText: "CryptoKities";
badgeSecondaryText: "";
badgeIconColor: "";
badgeIsLetterIdenticon: false }
ListElement { itemId: "i2"; titleId: "t2"; image: ""; color: "blue"; title: "core"; sectionName: "Channels"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i3"; titleId: "t3"; image: ""; color: "yellow"; title: "communities-phase3"; sectionName: "Channels"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i4"; titleId: "t4"; image: ""; color: "black"; title: "core-ui"; sectionName: "Channels"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i5"; titleId: "t5"; image: ""; color: "green"; title: "desktop"; sectionName: "Channels"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i6"; titleId: "t6"; image: ""; color: "red"; title: "Crocodile Vanilla Bird"; sectionName: "Chat"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i7"; titleId: "t7"; image: ""; color: "purple"; title: "carmen eth"; sectionName: "Chat"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i8"; titleId: "t8"; image: ""; color: "red"; title: "CryptoKitties"; sectionName: "Communities"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i9"; titleId: "t9"; image: ""; color: "blue"; title: "MyCommunity"; sectionName: "Communities"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i10"; titleId: "t10"; image: ""; color: "green"; title: "Foo"; sectionName: "Communities"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
}
property var searchResultsB: ListModel {
ListElement { itemId: "i1"; titleId: "t1"; title: "@Ant"; sectionName: "Messages"; time: "11:43 AM"; content: "<font color='#4360DF'>@John</font>, lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum ";
image: "";
color: "orange";
badgeImage: "";
badgePrimaryText: "CryptoKities";
badgeSecondaryText: "#design";
badgeIconColor: "pink"; badgeIsLetterIdenticon: true }
ListElement { itemId: "i2"; titleId: "t2"; image: ""; color: "blue"; title: "support"; sectionName: "Channels"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i3"; titleId: "t3"; image: ""; color: "red"; title: "desktop-ui"; sectionName: "Channels"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i4"; titleId: "t4"; image: ""; color: "orange"; title: "climate-change"; sectionName: "Chat"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i5"; titleId: "t5"; image: ""; color: "black"; title: "food"; sectionName: "Chat"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: "pink"; badgeIsLetterIdenticon: true }
ListElement { itemId: "i6"; titleId: "t6"; image: ""; color: "green"; title: "CryptoKitties"; sectionName: "Communities"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i7"; titleId: "t7"; image: ""; color: "purple"; title: "CryptoRangers"; sectionName: "Communities"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: ""; badgeIsLetterIdenticon: false }
ListElement { itemId: "i8"; titleId: "t8"; image: ""; color: "yellow"; title: "Foo"; sectionName: "Communities"; time: ""; content: ""; badgeImage: ""; badgePrimaryText: ""; badgeSecondaryText: ""; badgeIconColor: "orange"; badgeIsLetterIdenticon: true }
}
property ListModel optionsModel: ListModel {
ListElement {
value: "item_1"
title: "Item with icon"
imageSource: ""
iconName: "chat"
iconColor: ""
isIdenticon: false
subItems: [
ListElement {
value: "sub_item_1_1"
text: "Profile image item"
imageSource: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
iconName: ""
iconColor: ""
isIdenticon: false
},
ListElement {
value: "sub_item_1_2"
text: "identicon item"
imageSource: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
iconName: ""
iconColor: ""
isIdenticon: true
}]}
ListElement {
value: "item_2"
title: "Community item";
imageSource: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
iconName: ""
iconColor: ""
isIdenticon: false
subItems: [
ListElement {
value: "sub_item_2_1"
text: "welcome"
imageSource: ""
iconName: "channel"
iconColor: ""
isIdenticon: false
},
ListElement {
value: "sub_item_2_2"
text: "support"
imageSource: ""
iconName: "channel"
iconColor: ""
isIdenticon: false
},
ListElement {
value: "sub_item_2_3"
text: "news"
imageSource: ""
iconName: "channel"
iconColor: ""
isIdenticon: false
}]}
ListElement {
value: "item_3"
title: "Other";
imageSource: "";
iconName: "info"
iconColor: ""
isIdenticon: false
subItems: [
ListElement {
value: "sub_item_3_1"
text: "news"
imageSource: ""
iconName: "channel"
iconColor: ""
isIdenticon: false
}]}
ListElement {
value: "item_4"
title: "Letter identicon";
imageSource: "";
iconName: ""
iconColor: "red"
isIdenticon: false
subItems: [
ListElement {
value: "sub_item_4_1"
text: "news"
imageSource: ""
iconName: "channel"
iconColor: ""
isIdenticon: false
}]}
}
}
-41
View File
@@ -1,41 +0,0 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
GridLayout {
columns: 6
columnSpacing: 5
rowSpacing: 5
StatusLoadingIndicator {
color: Theme.palette.directColor4
}
StatusLetterIdenticon {
name: "#status"
}
StatusRoundedImage {
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
}
StatusBadge {}
StatusBadge {
value: 1
}
StatusBadge {
value: 10
}
StatusBadge {
value: 100
}
StatusRoundIcon {
icon.name: "info"
}
}
+3
View File
@@ -7,6 +7,8 @@ Item {
id: themeSwitchWrapper
signal checkedChanged()
property alias lightThemeEnabled: switchControl.checked
width: themeSwitch.width
height: themeSwitch.height
@@ -26,6 +28,7 @@ Item {
}
StatusSwitch {
id: switchControl
onCheckedChanged: themeSwitchWrapper.checkedChanged()
StatusToolTip {
@@ -188,4 +188,19 @@ GridLayout {
to: 100
value: 40
}
StatusBanner {
id: banner
width: 360
topPadding: 20
type: StatusBanner.Type.Danger
statusText: "Banner"
}
StatusProgressBar {
id: progressBar
text: "Weak"
value: 0.5
fillColor : Theme.palette.pinColor1
}
}
+443
View File
@@ -0,0 +1,443 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Layout 0.1
import StatusQ.Popups 0.1
Column {
spacing: 5
StatusChatToolBar {
chatInfoButton.title: "Some contact"
chatInfoButton.subTitle: "Contact"
chatInfoButton.icon.color: Theme.palette.miscColor7
chatInfoButton.type: StatusChatInfoButton.Type.OneToOneChat
}
StatusChatToolBar {
chatInfoButton.title: "Some contact"
chatInfoButton.subTitle: "Contact"
chatInfoButton.icon.color: Theme.palette.miscColor7
chatInfoButton.type: StatusChatInfoButton.Type.PublicChat
chatInfoButton.pinnedMessagesCount: 1
chatInfoButton.muted: true
}
StatusChatToolBar {
chatInfoButton.title: "Some contact"
chatInfoButton.subTitle: "Contact"
chatInfoButton.icon.color: Theme.palette.miscColor7
chatInfoButton.type: StatusChatInfoButton.Type.OneToOneChat
chatInfoButton.pinnedMessagesCount: 1
notificationCount: 1
}
Row {
spacing: 5
Button {
id: btn
text: "Append"
onClicked: {
buttons.append({
name: "Test community",
tooltipText: "Test Community"
})
}
}
QtObject {
id: appSectionType
readonly property int chat: 0
readonly property int community: 1
readonly property int wallet: 2
readonly property int browser: 3
readonly property int nodeManagement: 4
readonly property int profileSettings: 5
}
StatusAppNavBar {
sectionModel: ListModel {
ListElement {sectionId: "chat"; sectionType: 0; name: "Chat"; active: true; image: ""; icon: "chat"; color: ""; hasNotification: true; notificationsCount: 12}
}
regularNavBarButton: StatusNavBarTabButton {
anchors.horizontalCenter: parent.horizontalCenter
name: model.icon.length > 0? "" : model.name
icon.name: model.icon
icon.source: model.image
tooltip.text: model.name
autoExclusive: true
checked: model.active
badge.value: model.notificationsCount
badge.visible: model.hasNotification
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
}
}
StatusAppNavBar {
communityTypeRole: "sectionType"
communityTypeValue: appSectionType.community
sectionModel: ListModel {
ListElement {sectionId: "chat"; sectionType: 0; name: "Chat"; active: true; image: ""; icon: "chat"; color: ""; hasNotification: true; notificationsCount: 12}
ListElement {sectionId: "0x0001"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: true; notificationsCount: 12}
ListElement {sectionId: "wallet"; sectionType: 2; name: "Wallet"; active: false; image: ""; icon: "wallet"; color: ""; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "browser"; sectionType: 3; name: "Browser"; active: false; image: ""; icon: "bigger/browser"; color: ""; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "profile"; sectionType: 5; name: "Profile"; active: false; image: ""; icon: "bigger/settings"; color: ""; hasNotification: true; notificationsCount: 0}
}
property bool communityAdded: false
filterRegularItem: function(item) {
if(item.sectionType === appSectionType.community)
if(communityAdded)
return false
else
communityAdded = true
return true
}
filterCommunityItem: function(item) {
return item.sectionType === appSectionType.community
}
regularNavBarButton: StatusNavBarTabButton {
anchors.horizontalCenter: parent.horizontalCenter
name: model.icon.length > 0? "" : model.name
icon.name: model.icon
icon.source: model.image
tooltip.text: model.name
autoExclusive: true
checked: model.active
badge.value: model.notificationsCount
badge.visible: model.hasNotification
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
}
communityNavBarButton: StatusNavBarTabButton {
anchors.horizontalCenter: parent.horizontalCenter
name: model.icon.length > 0? "" : model.name
icon.name: model.icon
icon.source: model.image
tooltip.text: model.name
autoExclusive: true
checked: model.active
badge.value: model.notificationsCount
badge.visible: model.hasNotification
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
popupMenu: StatusPopupMenu {
StatusMenuItem {
text: qsTr("Invite People")
icon.name: "share-ios"
}
StatusMenuItem {
text: qsTr("View Community")
icon.name: "group"
}
StatusMenuItem {
text: qsTr("Edit Community")
icon.name: "edit"
enabled: false
}
StatusMenuSeparator {}
StatusMenuItem {
text: qsTr("Leave Community")
icon.name: "arrow-right"
icon.width: 14
iconRotation: 180
type: StatusMenuItem.Type.Danger
}
}
}
}
StatusAppNavBar {
communityTypeRole: "sectionType"
communityTypeValue: appSectionType.community
sectionModel: ListModel {
ListElement {sectionId: "chat"; sectionType: 0; name: "Chat"; active: true; image: ""; icon: "chat"; color: ""; hasNotification: true; notificationsCount: 12}
ListElement {sectionId: "0x0001"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: true; notificationsCount: 12}
ListElement {sectionId: "wallet"; sectionType: 2; name: "Wallet"; active: false; image: ""; icon: "wallet"; color: ""; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "browser"; sectionType: 3; name: "Browser"; active: false; image: ""; icon: "bigger/browser"; color: ""; hasNotification: false; notificationsCount: 0}
}
property bool communityAdded: false
filterRegularItem: function(item) {
if(item.sectionType === appSectionType.community)
if(communityAdded)
return false
else
communityAdded = true
return true
}
filterCommunityItem: function(item) {
return item.sectionType === appSectionType.community
}
regularNavBarButton: StatusNavBarTabButton {
anchors.horizontalCenter: parent.horizontalCenter
name: model.icon.length > 0? "" : model.name
icon.name: model.icon
icon.source: model.image
tooltip.text: model.name
autoExclusive: true
checked: model.active
badge.value: model.notificationsCount
badge.visible: model.hasNotification
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
}
communityNavBarButton: StatusNavBarTabButton {
anchors.horizontalCenter: parent.horizontalCenter
name: model.icon.length > 0? "" : model.name
icon.name: model.icon
icon.source: model.image
tooltip.text: model.name
autoExclusive: true
checked: model.active
badge.value: model.notificationsCount
badge.visible: model.hasNotification
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
popupMenu: StatusPopupMenu {
StatusMenuItem {
text: qsTr("Invite People")
icon.name: "share-ios"
}
StatusMenuItem {
text: qsTr("View Community")
icon.name: "group"
}
StatusMenuItem {
text: qsTr("Edit Community")
icon.name: "edit"
enabled: false
}
StatusMenuSeparator {}
StatusMenuItem {
text: qsTr("Leave Community")
icon.name: "arrow-right"
icon.width: 14
iconRotation: 180
type: StatusMenuItem.Type.Danger
}
}
}
}
StatusAppNavBar {
communityTypeRole: "sectionType"
communityTypeValue: appSectionType.community
sectionModel: ListModel {
ListElement {sectionId: "chat"; sectionType: 0; name: "Chat"; active: true; image: ""; icon: "chat"; color: ""; hasNotification: true; notificationsCount: 12}
ListElement {sectionId: "0x0001"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "0x0002"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "0x0003"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "0x0004"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: true; notificationsCount: 0}
ListElement {sectionId: "wallet"; sectionType: 2; name: "Wallet"; active: false; image: ""; icon: "wallet"; color: ""; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "browser"; sectionType: 3; name: "Browser"; active: false; image: ""; icon: "bigger/browser"; color: ""; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "profile"; sectionType: 5; name: "Profile"; active: false; image: ""; icon: "bigger/settings"; color: ""; hasNotification: false; notificationsCount: 0}
}
property bool communityAdded: false
filterRegularItem: function(item) {
if(item.sectionType === appSectionType.community)
if(communityAdded)
return false
else
communityAdded = true
return true
}
filterCommunityItem: function(item) {
return item.sectionType === appSectionType.community
}
regularNavBarButton: StatusNavBarTabButton {
anchors.horizontalCenter: parent.horizontalCenter
name: model.icon.length > 0? "" : model.name
icon.name: model.icon
icon.source: model.image
tooltip.text: model.name
autoExclusive: true
checked: model.active
badge.value: model.notificationsCount
badge.visible: model.hasNotification
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
}
communityNavBarButton: StatusNavBarTabButton {
anchors.horizontalCenter: parent.horizontalCenter
name: model.icon.length > 0? "" : model.name
icon.name: model.icon
icon.source: model.image
tooltip.text: model.name
autoExclusive: true
checked: model.active
badge.value: model.notificationsCount
badge.visible: model.hasNotification
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
popupMenu: StatusPopupMenu {
StatusMenuItem {
text: qsTr("Invite People")
icon.name: "share-ios"
}
StatusMenuItem {
text: qsTr("View Community")
icon.name: "group"
}
StatusMenuItem {
text: qsTr("Edit Community")
icon.name: "edit"
enabled: false
}
StatusMenuSeparator {}
StatusMenuItem {
text: qsTr("Leave Community")
icon.name: "arrow-right"
icon.width: 14
iconRotation: 180
type: StatusMenuItem.Type.Danger
}
}
}
}
StatusAppNavBar {
communityTypeRole: "sectionType"
communityTypeValue: appSectionType.community
sectionModel: ListModel {
ListElement {sectionId: "chat"; sectionType: 0; name: "Chat"; active: true; image: ""; icon: "chat"; color: ""; hasNotification: true; notificationsCount: 12}
ListElement {sectionId: "0x0001"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: true; notificationsCount: 12}
ListElement {sectionId: "0x0002"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "0x0003"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: true; notificationsCount: 0}
ListElement {sectionId: "0x0004"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: true; notificationsCount: 1}
ListElement {sectionId: "0x0005"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "0x0006"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: true; notificationsCount: 3}
ListElement {sectionId: "0x0007"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: true; notificationsCount: 5}
ListElement {sectionId: "0x0008"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: true; notificationsCount: 0}
ListElement {sectionId: "0x0009"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "0x0010"; sectionType: 1; name: "Test Community"; active: false; image: ""; icon: ""; color: "#00ff00"; hasNotification: true; notificationsCount: 11}
ListElement {sectionId: "wallet"; sectionType: 2; name: "Wallet"; active: false; image: ""; icon: "wallet"; color: ""; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "browser"; sectionType: 3; name: "Browser"; active: false; image: ""; icon: "bigger/browser"; color: ""; hasNotification: false; notificationsCount: 0}
ListElement {sectionId: "profile"; sectionType: 5; name: "Profile"; active: false; image: ""; icon: "bigger/settings"; color: ""; hasNotification: true; notificationsCount: 0}
}
property bool communityAdded: false
filterRegularItem: function(item) {
if(item.sectionType === appSectionType.community)
if(communityAdded)
return false
else
communityAdded = true
return true
}
filterCommunityItem: function(item) {
return item.sectionType === appSectionType.community
}
regularNavBarButton: StatusNavBarTabButton {
anchors.horizontalCenter: parent.horizontalCenter
name: model.icon.length > 0? "" : model.name
icon.name: model.icon
icon.source: model.image
tooltip.text: model.name
autoExclusive: true
checked: model.active
badge.value: model.notificationsCount
badge.visible: model.hasNotification
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
}
communityNavBarButton: StatusNavBarTabButton {
anchors.horizontalCenter: parent.horizontalCenter
name: model.icon.length > 0? "" : model.name
icon.name: model.icon
icon.source: model.image
tooltip.text: model.name
autoExclusive: true
checked: model.active
badge.value: model.notificationsCount
badge.visible: model.hasNotification
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
popupMenu: StatusPopupMenu {
StatusMenuItem {
text: qsTr("Invite People")
icon.name: "share-ios"
}
StatusMenuItem {
text: qsTr("View Community")
icon.name: "group"
}
StatusMenuItem {
text: qsTr("Edit Community")
icon.name: "edit"
enabled: false
}
StatusMenuSeparator {}
StatusMenuItem {
text: qsTr("Leave Community")
icon.name: "arrow-right"
icon.width: 14
iconRotation: 180
type: StatusMenuItem.Type.Danger
}
}
}
}
}
}
@@ -4,6 +4,7 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Utils 0.1
GridLayout {
columns: 1
@@ -25,7 +26,7 @@ GridLayout {
badge.value: 1
}
StatusNavigationListItem {
title: "Menu Item (selected)"
title: "Menu Item (selected) with very long text"
selected: true
icon.name: "info"
badge.value: 1
@@ -64,6 +65,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"
@@ -85,7 +92,8 @@ GridLayout {
StatusChatListItem {
name: "has-mentions"
type: StatusChatListItem.Type.PublicChat
badge.value: 1
hasUnreadMessages: true
notificationsCount: 1
}
StatusChatListItem {
@@ -100,7 +108,7 @@ GridLayout {
type: StatusChatListItem.Type.PublicChat
muted: true
hasUnreadMessages: true
badge.value: 1
notificationsCount: 1
}
StatusChatListItem {
@@ -130,7 +138,7 @@ GridLayout {
selected: true
muted: true
hasUnreadMessages: true
badge.value: 1
notificationsCount: 1
}
@@ -321,6 +329,43 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
badge.icon.isLetterIdenticon: true
}
StatusListItem {
title: "List Item with Tags"
icon.isLetterIdenticon: true
bottomModel: 3
bottomDelegate: StatusListItemTag {
title: "tag"
icon.isLetterIdenticon: true
}
}
StatusListItem {
title: "List Item with Inline Tags"
icon.isLetterIdenticon: true
tagsModel : 2
tagsDelegate: StatusListItemTag {
color: "blue"
height: 24
radius: 6
closeButtonVisible: false
icon.emoji: "😁"
icon.emojiSize: Emoji.size.verySmall
icon.isLetterIdenticon: true
title: "helloworld.eth"
titleText.font.pixelSize: 12
titleText.color: Theme.palette.indirectColor1
}
}
StatusListItem {
title: "List Item with Emoji"
subTitle: "Emoji"
icon.emoji: "😁"
icon.color: "yellow"
icon.letterSize: 14
icon.isLetterIdenticon: true
}
StatusDescriptionListItem {
title: "Title"
subTitle: "Subtitle"
@@ -345,4 +390,55 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
title: "Contact requests"
requestsCount: 3
}
StatusMemberListItem {
nickName: "This is an example"
userName: "annabelle"
chatKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
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: StatusContactVerificationIcons.TrustedType.Untrustworthy
}
StatusMemberListItem {
nickName: "very-long-annoying-nickname.eth"
isOnline: false
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
}
StatusMemberListItem {
nickName: "This girl I know from work"
userName: "annabelle"
isOnline: true
}
StatusMemberListItem {
nickName: "Mark Cuban"
userName: "annabelle"
chatKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
isMutualContact: true
image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
image.isIdenticon: true
}
}
+61
View File
@@ -0,0 +1,61 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
ColumnLayout {
GridLayout {
Layout.fillWidth: true
Layout.fillHeight: true
columns: 6
columnSpacing: 5
rowSpacing: 5
StatusLoadingIndicator {
color: Theme.palette.directColor4
}
StatusLetterIdenticon {
name: "#status"
}
StatusRoundedImage {
image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
}
StatusBadge {}
StatusBadge {
value: 1
}
StatusBadge {
value: 10
}
StatusBadge {
value: 100
}
StatusRoundIcon {
icon.name: "info"
}
}
Flow {
Layout.fillWidth: true
spacing: 4
Repeater {
model: 12
StatusLetterIdenticon {
name: "A"
color: Theme.palette.userCustomizationColors[index]
letterSize: 16
}
}
}
}
@@ -73,6 +73,16 @@ Column {
onClicked: spellMenu.open()
}
StatusButton {
text: "Modal with Editable Title"
onClicked: editTitleModal.open()
}
StatusButton {
text: "Modal with Advanced Header/Footer"
onClicked: advancedHeaderFooterModal.open()
}
StatusModal {
id: simpleModal
anchors.centerIn: parent
@@ -341,6 +351,49 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
}
}
StatusModal {
id: editTitleModal
anchors.centerIn: parent
header.title: "This title can be edited"
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"}
+104
View File
@@ -0,0 +1,104 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQml.Models 2.2
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
import StatusQ.Components 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
ListView {
id: messageList
anchors.fill: parent
anchors.margins: 15
clip: true
delegate: StatusMessage {
id: delegate
width: parent.width
audioMessageInfoText: "Audio Message"
cancelButtonText: "Cancel"
saveButtonText: "Save"
loadingImageText: "Loading image..."
errorLoadingImageText: "Error loading the image"
resendText: "Resend"
pinnedMsgInfoText: "Pinned by"
messageDetails: StatusMessageDetails {
contentType: model.contentType
messageContent: model.messageContent
amISender: model.amIsender
displayName: model.userName
secondaryName: model.localName !== "" && model.ensName.startsWith("@") ? model.ensName: ""
chatID: model.chatKey
profileImage: StatusImageSettings {
width: 40
height: 40
source: model.profileImage
isIdenticon: model.isIdenticon
}
messageText: model.message
hasMention: model.hasMention
isMutualContact: model.isMutualContact
trustIndicator: model.trustIndicator
isPinned: model.isPinned
pinnedBy: model.pinnedBy
hasExpired: model.hasExpired
}
timestamp.text: "10:00 am"
timestamp.tooltip.text: "10:01 am"
// reply related data
isAReply: model.isReply
replyDetails: StatusMessageDetails {
amISender: model.isReply ? model.replyAmISender : ""
displayName: model.isReply ? model.replySenderName: ""
profileImage: StatusImageSettings {
width: 20
height: 20
source: model.isReply ? model.replyProfileImage: ""
isIdenticon: model.isReply ? model.replyIsIdenticon: ""
}
messageText: model.isReply ? model.replyMessageText: ""
contentType: model.replyContentType
messageContent: model.replyMessageContent
}
quickActions: [
StatusFlatRoundButton {
id: emojiBtn
width: 32
height: 32
icon.name: "reaction-b"
type: StatusFlatRoundButton.Type.Tertiary
tooltip.text: "Add reaction"
},
StatusFlatRoundButton {
id: replyBtn
width: 32
height: 32
icon.name: "reply"
type: StatusFlatRoundButton.Type.Tertiary
tooltip.text: "Reply"
},
StatusFlatRoundButton {
width: 32
height: 32
icon.name: "tiny/edit"
type: StatusFlatRoundButton.Type.Tertiary
tooltip.text: "Edit"
onClicked: {
delegate.editMode = !delegate.editMode
}
},
StatusFlatRoundButton {
id: otherBtn
width: 32
height: 32
icon.name: "more"
type: StatusFlatRoundButton.Type.Tertiary
tooltip.text: "More"
}
]
}
}
+99
View File
@@ -0,0 +1,99 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Page {
id: root
anchors.fill: parent
anchors.margins: 16
property ListModel contactsModel: null
background: null
header: RowLayout {
id: headerRow
width: parent.width
height: tagSelector.height
anchors.right: parent.right
anchors.rightMargin: 8
StatusTagSelector {
id: tagSelector
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: 17
maxHeight: root.height
toLabelText: qsTr("To: ")
warningText: qsTr("USER LIMIT REACHED")
listLabel: qsTr("Contacts")
ringSpecModelGetter: function(pubKey) {
//for simulation purposes only, in real app
//this would be Utils.getColorHashAsJson(pubKey)
var index = -1;
if (!!contactsModel) {
for (var i = 0; i < contactsModel.count; i++) {
if (contactsModel.get(i).publicId === pubKey) {
index = i;
}
}
return contactsModel.get(index).ringSpecModel;
} else {
return null;
}
}
compressedKeyGetter: function(pubKey) {
//for simulation purposes only, in real app
//this would be Utils.getCompressedPk(pubKey);
var possibleCharacters = pubKey.split('');
var randomStringLength = 12; // assuming you want random strings of 12 characters
var randomString = [];
for (var i=0; i<randomStringLength; ++i) {
var index = (Math.random() * possibleCharacters.length).toFixed(0);
var nextChar = possibleCharacters[index];
randomString.push(nextChar);
}
return randomString.join().toString().replace(/,/g, '');
}
onTextChanged: {
sortModel(root.contactsModel);
}
Component.onCompleted: {
textEdit.forceActiveFocus();
sortModel(root.contactsModel);
}
}
StatusButton {
implicitHeight: 44
Layout.alignment: Qt.AlignTop
enabled: (tagSelector.namesModel.count > 0)
text: "Confirm"
}
}
contentItem: Item {
anchors.fill: parent
anchors.topMargin: 68
StatusBaseText {
visible: (contactsModel.count === 0)
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: 15
color: Theme.palette.baseColor1
text: qsTr("You can only send direct messages to your Contacts. \n\n
Send a contact request to the person you would like to chat with, you will be\n able to
chat with them once they have accepted your contact request.")
Component.onCompleted: {
if (visible) {
tagSelector.enabled = false;
}
}
}
}
}
@@ -0,0 +1,111 @@
import QtQuick 2.12
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
StatusModal {
id: root
anchors.centerIn: parent
header.title: "Cryptokitties"
header.subTitle: "Public Community"
header.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
contentItem: Column {
width: root.width
StatusModalDivider {
bottomPadding: 8
}
StatusBaseText {
text: "A community of cat lovers, meow!"
verticalAlignment: Text.AlignVCenter
font.pixelSize: 15
height: 46
color: Theme.palette.directColor1
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.rightMargin: 16
}
StatusModalDivider {
topPadding: 8
bottomPadding: 8
}
StatusDescriptionListItem {
title: "Share community"
subTitle: "https://join.status.im/u/0x04...45f19"
tooltip.text: "Copy to clipboard"
icon.name: "copy"
iconButton.onClicked: tooltip.visible = !tooltip.visible
width: parent.width
}
StatusModalDivider {
topPadding: 8
bottomPadding: 8
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Members"
icon.name: "group-chat"
label: "184"
components: [
StatusIcon {
icon: "chevron-down"
rotation: 270
color: Theme.palette.baseColor1
}
]
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Notifications"
icon.name: "notification"
components: [
StatusSwitch {}
]
}
StatusModalDivider {
topPadding: 8
bottomPadding: 8
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Edit community"
icon.name: "edit"
type: StatusListItem.Type.Secondary
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Transfer ownership"
icon.name: "exchange"
type: StatusListItem.Type.Secondary
}
StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Leave community"
icon.name: "arrow-right"
icon.rotation: 180
type: StatusListItem.Type.Secondary
}
}
}
@@ -0,0 +1,40 @@
import QtQuick 2.12
import StatusQ.Controls 0.1
import StatusQ.Core 0.1
import StatusQ.Popups 0.1
import StatusQ.Core.Theme 0.1
StatusModal {
id: root
header.title: "Contact Requests"
headerActionButton: StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
width: 32
height: 32
icon.width: 20
icon.height: 20
icon.name: "notification"
}
contentItem: StatusBaseText {
anchors.centerIn: parent
text: "Contact request will be shown here"
font.pixelSize: 15
color: Theme.palette.directColor1
}
rightButtons: [
StatusButton {
text: "Decline all"
type: StatusBaseButton.Type.Danger
onClicked: root.close()
},
StatusButton {
text: "Accept all"
onClicked: root.close()
}
]
}
+191
View File
@@ -0,0 +1,191 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
import StatusQ.Components 0.1
import StatusQ.Layout 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import "data" 1.0
StatusAppThreePanelLayout {
id: root
property bool createChat: false
leftPanel: Item {
anchors.fill: parent
StatusNavigationPanelHeadline {
id: headline
anchors.top: parent.top
anchors.topMargin: 16
anchors.horizontalCenter: parent.horizontalCenter
text: "Chat"
}
RowLayout {
id: searchInputWrapper
width: 288
height: searchInput.height
anchors.top: headline.bottom
anchors.topMargin: 16
anchors.horizontalCenter: parent.horizontalCenter
StatusBaseInput {
id: searchInput
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
implicitHeight: 36
topPadding: 8
bottomPadding: 8
placeholderText: "Search"
icon.name: "search"
}
StatusIconTabButton {
icon.name: "public-chat"
}
StatusIconTabButton {
icon.name: "edit"
onClicked: {
root.createChat = !root.createChat;
}
}
}
Column {
anchors.top: searchInputWrapper.bottom
anchors.topMargin: 16
anchors.horizontalCenter: parent.horizontalCenter
spacing: 8
StatusContactRequestsIndicatorListItem {
anchors.horizontalCenter: parent.horizontalCenter
title: "Contact requests"
requestsCount: 3
sensor.onClicked: demoContactRequestsModal.open()
}
StatusChatList {
model: Models.demoChatListItems
highlightItem: !root.createChat
onChatItemUnmuted: {
for (var i = 0; i < Models.demoChatListItems.count; i++) {
let item = Models.demoChatListItems.get(i);
if (item.chatId === id) {
Models.demoChatListItems.setProperty(i, "muted", false)
}
}
}
popupMenu: StatusPopupMenu {
property string chatId
openHandler: function (id) {
chatId = id
}
StatusMenuItem {
text: "View Profile"
icon.name: "group-chat"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Mute chat"
icon.name: "notification"
}
StatusMenuItem {
text: "Mark as Read"
icon.name: "checkmark-circle"
}
StatusMenuItem {
text: "Clear history"
icon.name: "close-circle"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Delete chat"
icon.name: "delete"
type: StatusMenuItem.Type.Danger
}
}
}
}
}
centerPanel: Loader {
anchors.fill: parent
sourceComponent: root.createChat ? createChatView : chatChannelView
Component {
id: createChatView
CreateChatView {
contactsModel: Models.membersListModel
}
}
Component {
id: chatChannelView
ChatChannelView {
model: Models.chatMessagesModel
}
}
}
rightPanel: Item {
anchors.fill: parent
StatusChatToolBar {
anchors.top: parent.top
width: parent.width
chatInfoButton.title: "Amazing Funny Squirrel"
chatInfoButton.subTitle: "Contact"
chatInfoButton.icon.color: Theme.palette.miscColor7
chatInfoButton.type: StatusChatInfoButton.Type.OneToOneChat
chatInfoButton.pinnedMessagesCount: 1
searchButton.visible: false
membersButton.visible: false
notificationCount: 1
onNotificationButtonClicked: notificationCount = 0
popupMenu: StatusPopupMenu {
id: contextMenu
StatusMenuItem {
text: "Mute Chat"
icon.name: "notification"
}
StatusMenuItem {
text: "Mark as Read"
icon.name: "checkmark-circle"
}
StatusMenuItem {
text: "Clear History"
icon.name: "close-circle"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Leave Chat"
icon.name: "arrow-right"
icon.width: 14
iconRotation: 180
type: StatusMenuItem.Type.Danger
}
}
}
}
}
+273
View File
@@ -0,0 +1,273 @@
import QtQuick 2.12
import QtQuick.Controls 2.14
import StatusQ.Core 0.1
import StatusQ.Popups 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Layout 0.1
import StatusQ.Core.Theme 0.1
import "data" 1.0
StatusAppThreePanelLayout {
id: root
property string communityDetailModalTitle: ""
property string communityDetailModalImage: ""
signal chatInfoButtonClicked()
handle: Rectangle {
implicitWidth: 5
color: SplitHandle.pressed ? Theme.palette.baseColor2
: (SplitHandle.hovered ? Qt.darker(Theme.palette.baseColor5, 1.1) : "transparent")
}
leftPanel: Item {
id: leftPanel
StatusChatInfoToolBar {
id: statusChatInfoToolBar
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
chatInfoButton.title: "CryptoKitties"
chatInfoButton.subTitle: "128 Members"
chatInfoButton.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
chatInfoButton.icon.color: Theme.palette.miscColor6
chatInfoButton.onClicked: { chatInfoButtonClicked(); }
popupMenu: StatusPopupMenu {
StatusMenuItem {
text: "Create channel"
icon.name: "channel"
}
StatusMenuItem {
text: "Create category"
icon.name: "channel-category"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Invite people"
icon.name: "share-ios"
}
}
}
ScrollView {
id: scrollView
anchors.top: statusChatInfoToolBar.bottom
anchors.topMargin: 8
anchors.bottom: parent.bottom
width: leftPanel.width
contentHeight: communityCategories.height
clip: true
StatusChatListAndCategories {
id: communityCategories
width: leftPanel.width
height: implicitHeight > (leftPanel.height - 64) ? implicitHeight + 8 : leftPanel.height - 64
draggableItems: true
draggableCategories: false
model: Models.demoCommunityChatListItems
showCategoryActionButtons: true
categoryPopupMenu: StatusPopupMenu {
property string categoryId
openHandler: function (id) {
categoryId = id
}
StatusMenuItem {
text: "Mute Category"
icon.name: "notification"
}
StatusMenuItem {
text: "Mark as Read"
icon.name: "checkmark-circle"
}
StatusMenuItem {
text: "Edit Category"
icon.name: "edit"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Delete Category"
icon.name: "delete"
type: StatusMenuItem.Type.Danger
}
}
chatListPopupMenu: StatusPopupMenu {
property string chatId
StatusMenuItem {
text: "Mute chat"
icon.name: "notification"
}
StatusMenuItem {
text: "Mark as Read"
icon.name: "checkmark-circle"
}
StatusMenuItem {
text: "Clear history"
icon.name: "close-circle"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Delete chat"
icon.name: "delete"
type: StatusMenuItem.Type.Danger
}
}
popupMenu: StatusPopupMenu {
StatusMenuItem {
text: "Create channel"
icon.name: "channel"
}
StatusMenuItem {
text: "Create category"
icon.name: "channel-category"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Invite people"
icon.name: "share-ios"
}
}
}
}
}
centerPanel: Item {
StatusChatToolBar {
id: statusChatToolBar
anchors.top: parent.top
width: parent.width
chatInfoButton.title: "general"
chatInfoButton.subTitle: "Community Chat"
chatInfoButton.icon.color: Theme.palette.miscColor6
chatInfoButton.type: StatusChatInfoButton.Type.CommunityChat
onSearchButtonClicked: {
searchButton.highlighted = !searchButton.highlighted;
searchPopup.setSearchSelection(communityDetailModalTitle,
"",
communityDetailModalImage);
searchPopup.open();
}
membersButton.onClicked: membersButton.highlighted = !membersButton.highlighted
onMembersButtonClicked: {
root.showRightPanel = !root.showRightPanel;
}
}
StatusSearchPopup {
id: searchPopup
searchOptionsPopupMenu: searchPopupMenu
onAboutToHide: {
if (searchPopupMenu.visible) {
searchPopupMenu.close();
}
//clear menu
for (var i = 2; i < searchPopupMenu.count; i++) {
searchPopupMenu.removeItem(searchPopupMenu.takeItem(i));
}
}
onClosed: {
statusChatToolBar.searchButton.highlighted = false
searchPopupMenu.dismiss();
}
onSearchTextChanged: {
if (searchPopup.searchText !== "") {
searchPopup.loading = true;
searchModelSimTimer.start();
} else {
searchPopup.searchResults = [];
searchModelSimTimer.stop();
}
}
Timer {
id: searchModelSimTimer
interval: 500
onTriggered: {
if (searchPopup.searchText.startsWith("c")) {
searchPopup.searchResults = Models.searchResultsA;
} else {
searchPopup.searchResults = Models.searchResultsB;
}
searchPopup.loading = false;
}
}
}
StatusSearchLocationMenu {
id: searchPopupMenu
searchPopup: searchPopup
locationModel: Models.optionsModel
}
}
rightPanel: Item {
id: rightPanel
StatusBaseText {
id: titleText
anchors.top: parent.top
anchors.topMargin:16
anchors.left: parent.left
anchors.leftMargin: 16
opacity: (rightPanel.width > 50) ? 1.0 : 0.0
visible: (opacity > 0.1)
font.pixelSize: 15
text: qsTr("Members")
}
ListView {
anchors.top: titleText.bottom
anchors.topMargin: 16
anchors.left: parent.left
anchors.leftMargin: 8
anchors.right: parent.right
anchors.rightMargin: 8
anchors.bottom: parent.bottom
anchors.bottomMargin: 16
boundsBehavior: Flickable.StopAtBounds
model: Models.membersListModel
delegate: StatusMemberListItem {
implicitWidth: parent.width
nickName: model.nickName
userName: model.name
chatKey: model.publicId
trustIndicator: model.trustIndicator
isMutualContact: model.isMutualContact
image.source: model.icon
image.isIdenticon: model.isIdenticon
isOnline: model.onlineStatus
ringSettings.ringSpecModel: model.ringSpecModel
}
}
}
}
@@ -0,0 +1,77 @@
import QtQuick 2.12
import QtQuick.Controls 2.14
import StatusQ.Components 0.1
import StatusQ.Layout 0.1
import StatusQ.Core.Theme 0.1
import "data" 1.0
StatusAppTwoPanelLayout {
id: root
leftPanel: Item {
anchors.fill: parent
StatusNavigationPanelHeadline {
id: profileHeadline
anchors.top: parent.top
anchors.topMargin: 16
anchors.horizontalCenter: parent.horizontalCenter
text: "Profile"
}
ScrollView {
anchors.top: profileHeadline.bottom
anchors.topMargin: 16
anchors.bottom: parent.bottom
width: parent.width
contentHeight: profileMenuItems.height + 8
contentWidth: parent.width
clip: true
Column {
id: profileMenuItems
anchors.horizontalCenter: parent.horizontalCenter
spacing: 4
Repeater {
model: Models.demoProfileGeneralMenuItems
delegate: StatusNavigationListItem {
title: model.title
icon.name: model.icon
}
}
StatusListSectionHeadline { text: "Settings" }
Repeater {
model: Models.demoProfileSettingsMenuItems
delegate: StatusNavigationListItem {
title: model.title
icon.name: model.icon
}
}
Item {
id: invisibleSeparator
height: 16
width: parent.width
}
Repeater {
model: Models.demoProfileOtherMenuItems
delegate: StatusNavigationListItem {
title: model.title
icon.name: model.icon
}
}
}
}
}
rightPanel: Item {
anchors.fill: parent
}
}
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

+1
View File
@@ -0,0 +1 @@
singleton Models 1.0 Models.qml
+5
View File
@@ -11,6 +11,11 @@ int main(int argc, char *argv[])
#endif
SandboxApp app(argc, argv);
app.setOrganizationName("Status");
app.setOrganizationDomain("status.im");
app.setApplicationName("Sandbox");
app.startEngine();
return app.exec();
+199 -210
View File
@@ -2,6 +2,8 @@ import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import QtGraphicalEffects 1.13
import QtQuick.Layouts 1.14
import Qt.labs.settings 1.0
import Sandbox 0.1
@@ -12,6 +14,8 @@ import StatusQ.Components 0.1
import StatusQ.Layout 0.1
import StatusQ.Platform 0.1
import "demoapp/data" 1.0
StatusWindow {
id: rootWindow
width: Qt.platform.os == "ios" || Qt.platform.os == "android" ? Screen.width
@@ -29,11 +33,30 @@ StatusWindow {
property real factor: 1.0
Component.onCompleted: {
Theme.palette = lightTheme
apiDocsButton.checked = true
Component.onCompleted: rootWindow.updatePosition()
rootWindow.updatePosition();
QtObject {
id: appSectionType
readonly property int chat: 0
readonly property int community: 1
readonly property int wallet: 2
readonly property int browser: 3
readonly property int nodeManagement: 4
readonly property int profileSettings: 5
readonly property int apiDocumentation: 100
readonly property int demoApp: 101
}
function setActiveItem(sectionId) {
for (var i = 0; i < Models.mainAppSectionsModel.count; i++) {
let item = Models.mainAppSectionsModel.get(i)
if (item.sectionId !== sectionId) {
Models.mainAppSectionsModel.setProperty(i, "active", false);
continue
}
Models.mainAppSectionsModel.setProperty(i, "active", true);
}
}
StatusAppLayout {
@@ -43,37 +66,36 @@ StatusWindow {
appNavBar: StatusAppNavBar {
height: rootWindow.height
navBarChatButton: StatusNavBarTabButton {
icon.name: "refresh"
tooltip.text: "Reload App"
onClicked: app.restartQml()
}
communityTypeRole: "sectionType"
communityTypeValue: appSectionType.community
sectionModel: Models.mainAppSectionsModel
navBarTabButtons: [
StatusNavBarTabButton {
id: apiDocsButton
icon.name: "edit"
tooltip.text: "API Documentation"
onClicked: {
stackView.clear()
regularNavBarButton: StatusNavBarTabButton {
anchors.horizontalCenter: parent.horizontalCenter
name: model.icon.length > 0? "" : model.name
icon.name: model.icon
icon.source: model.image
tooltip.text: model.name
autoExclusive: true
checked: model.active
badge.value: model.notificationsCount
badge.visible: model.hasNotification
badge.border.color: hovered ? Theme.palette.statusBadge.hoverBorderColor : Theme.palette.statusBadge.borderColor
badge.border.width: 2
onClicked: {
stackView.clear()
if(model.sectionType === appSectionType.apiDocumentation)
{
stackView.push(libraryDocumentationCmp)
checked = !checked
demoAppButton.checked = false
rootWindow.setActiveItem(sectionId)
}
},
StatusNavBarTabButton {
id: demoAppButton
icon.name: "status"
tooltip.text: "Demo Application"
checked: stackView.currentItem == demoAppCmp
onClicked: {
stackView.clear()
else if(model.sectionType === appSectionType.demoApp)
{
stackView.push(demoAppCmp)
checked = !checked
apiDocsButton.checked = false
rootWindow.setActiveItem(model.sectionId)
}
}
]
}
}
appView: StackView {
@@ -87,12 +109,10 @@ StatusWindow {
anchors.topMargin: 32
anchors.right: parent.right
anchors.rightMargin: 32
onCheckedChanged: {
if (Theme.palette === rootWindow.lightTheme) {
Theme.palette = rootWindow.darkTheme
} else {
Theme.palette = rootWindow.lightTheme
}
lightThemeEnabled: storeSettings.lightTheme
onLightThemeEnabledChanged: {
Theme.palette = lightThemeEnabled ? rootWindow.darkTheme : rootWindow.lightTheme
storeSettings.lightTheme = lightThemeEnabled
}
}
}
@@ -101,6 +121,16 @@ StatusWindow {
id: libraryDocumentationCmp
StatusAppTwoPanelLayout {
id: mainPageView
function page(name, fillPage) {
storeSettings.fillPage = fillPage ? true : false
viewLoader.source = Qt.resolvedUrl("./pages/" + name + "Page.qml");
}
function control(name) {
viewLoader.source = Qt.resolvedUrl("./controls/" + name + ".qml");
storeSettings.fillPage = false
}
leftPanel: Item {
anchors.fill: parent
@@ -120,122 +150,167 @@ StatusWindow {
StatusListSectionHeadline { text: "StatusQ.Core" }
StatusNavigationListItem {
title: "Icons"
selected: page.sourceComponent == iconsComponent
onClicked: page.sourceComponent = iconsComponent
title: "Icons"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.control(title);
}
StatusListSectionHeadline { text: "StatusQ.Layout" }
StatusNavigationListItem {
title: "Layouts"
selected: page.sourceComponent == layoutComponent
onClicked: page.sourceComponent = layoutComponent
title: "Layouts"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.control(title.substring(0, title.length - 1));
}
StatusListSectionHeadline { text: "StatusQ.Controls" }
StatusNavigationListItem {
title: "Buttons"
selected: page.sourceComponent == buttonsComponent
onClicked: page.sourceComponent = buttonsComponent
title: "Buttons"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.control(title);
}
StatusNavigationListItem {
title: "StatusSwitchTab"
selected: page.sourceComponent == statusTabSwitchesComponent
onClicked: page.sourceComponent = statusTabSwitchesComponent
title: "StatusSwitchTab"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page("StatusTabSwitch");
}
StatusNavigationListItem {
title: "StatusChatCommandButton"
selected: page.sourceComponent == statusChatCommandButtonPageComponent
onClicked: page.sourceComponent = statusChatCommandButtonPageComponent
title: "StatusChatCommandButton"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "Controls"
selected: page.sourceComponent == controlsComponent
onClicked: page.sourceComponent = controlsComponent
title: "Controls"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.control(title);
}
StatusNavigationListItem {
title: "StatusTabBarButton"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusTabBarIconButton"
selected: page.sourceComponent == statusTabBarIconButtonPageComponent
onClicked: page.sourceComponent = statusTabBarIconButtonPageComponent
title: "StatusTabBarIconButton"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusInput"
selected: page.sourceComponent == statusInputPageComponent
onClicked: page.sourceComponent = statusInputPageComponent
title: "StatusInput"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusSelect"
selected: page.sourceComponent == statusSelectPageComponent
onClicked: page.sourceComponent = statusSelectPageComponent
title: "StatusSelect"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusAccountSelector"
selected: page.sourceComponent == statusAccountSelectorPageComponent
onClicked: page.sourceComponent = statusAccountSelectorPageComponent
title: "StatusAccountSelector"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusAssetSelector"
selected: page.sourceComponent == statusAssetSelectorPageComponent
onClicked: page.sourceComponent = statusAssetSelectorPageComponent
title: "StatusAssetSelector"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusColorSelector"
selected: page.sourceComponent == statusColorSelectorPageComponent
onClicked: page.sourceComponent = statusColorSelectorPageComponent
title: "StatusColorSelector"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusWalletColorButton"
selected: page.sourceComponent == statusWalletColorButtonPageComponent
onClicked: page.sourceComponent = statusWalletColorButtonPageComponent
title: "StatusWalletColorButton"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusWalletColorSelect"
selected: page.sourceComponent == statusWalletColorSelectPageComponent
onClicked: page.sourceComponent = statusWalletColorSelectPageComponent
title: "StatusWalletColorSelect"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusPasswordStrengthIndicator"
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"
selected: page.sourceComponent == statusAddressPageComponent
onClicked: page.sourceComponent = statusAddressPageComponent
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "List Items"
selected: page.sourceComponent == listItemsComponent
onClicked: page.sourceComponent = listItemsComponent
selected: viewLoader.source.toString().includes(title.replace(/\s+/g, ''))
onClicked: mainPageView.control(title.replace(/\s+/g, ''));
}
StatusNavigationListItem {
title: "StatusChatInfoToolBar"
selected: page.sourceComponent == chatInfoToolBarComponent
onClicked: page.sourceComponent = chatInfoToolBarComponent
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "Others"
selected: page.sourceComponent == othersComponent
onClicked: page.sourceComponent = othersComponent
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.control(title);
}
StatusNavigationListItem {
title: "StatusExpandableItem"
selected: page.sourceComponent == settingsComponent
onClicked: page.sourceComponent = settingsComponent
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page("StatusExpandableSettingsItem");
}
StatusNavigationListItem {
title: "StatusTagSelector"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusToastMessage"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusWizardStepper"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusListPicker"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusListSectionHeadline { text: "StatusQ.Popup" }
StatusNavigationListItem {
title: "StatusPopupMenu"
selected: page.sourceComponent == popupMenuComponent
onClicked: page.sourceComponent = popupMenuComponent
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusModal"
selected: page.sourceComponent == statusModalComponent
onClicked: page.sourceComponent = statusModalComponent
selected: viewLoader.source.toString().includes("Popups")
onClicked: mainPageView.control("Popups");
}
StatusListSectionHeadline { text: "StatusQ.Platform" }
StatusNavigationListItem {
title: "StatusMacNotification"
selected: page.sourceComponent == notificationComponent
onClicked: page.sourceComponent = notificationComponent
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusColorSelectorGrid"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusImageCropPanel"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title, true);
}
}
}
@@ -244,8 +319,11 @@ StatusWindow {
rightPanel: Item {
id: rightPanel
anchors.fill: parent
ScrollView {
visible: !storeSettings.fillPage
anchors.fill: parent
anchors.topMargin: 64
contentHeight: (pageWrapper.height + pageWrapper.anchors.topMargin) * rootWindow.factor
contentWidth: (pageWrapper.width * rootWindow.factor)
clip: true
@@ -254,17 +332,32 @@ StatusWindow {
id: pageWrapper
width: rightPanel.width
anchors.top: parent.top
anchors.topMargin: 64
height: Math.max(rootWindow.height, page.height + 128)
height: Math.max(rootWindow.height, viewLoader.height + 128)
scale: rootWindow.factor
Loader {
id: page
active: true
id: viewLoader
active: !storeSettings.fillPage
anchors.centerIn: parent
sourceComponent: iconsComponent
source: storeSettings.selected.length === 0 ? mainPageView.control("Icons") : storeSettings.selected
onSourceChanged: {
storeSettings.selected = viewLoader.source
if (source.toString().includes("Icons")) {
item.iconColor = Theme.palette.primaryColor1;
}
}
}
}
}
Loader {
active: storeSettings.fillPage
anchors.fill: parent
anchors.topMargin: 64
visible: storeSettings.fillPage
clip: true
source: viewLoader.source
}
}
}
}
@@ -292,116 +385,6 @@ StatusWindow {
}
}
Component {
id: iconsComponent
Icons { iconColor: Theme.palette.primaryColor1 }
}
Component {
id: controlsComponent
Controls {}
}
Component {
id: statusInputPageComponent
StatusInputPage {}
}
Component {
id: statusSelectPageComponent
StatusSelectPage {}
}
Component {
id: statusAccountSelectorPageComponent
StatusAccountSelectorPage {}
}
Component {
id: statusAssetSelectorPageComponent
StatusAssetSelectorPage {}
}
Component {
id: statusColorSelectorPageComponent
StatusColorSelectorPage {}
}
Component {
id: statusTabBarIconButtonPageComponent
StatusTabBarIconButtonPage {}
}
Component {
id: statusWalletColorButtonPageComponent
StatusWalletColorButtonPage {}
}
Component {
id: statusWalletColorSelectPageComponent
StatusWalletColorSelectPage {}
}
Component {
id: listItemsComponent
ListItems {}
}
Component {
id: statusAddressPageComponent
StatusAddressPage {}
}
Component {
id: layoutComponent
Layout {}
}
Component {
id: othersComponent
Others {}
}
Component {
id: buttonsComponent
Buttons {}
}
Component {
id: statusChatCommandButtonPageComponent
StatusChatCommandButtonPage {}
}
Component {
id: popupMenuComponent
StatusPopupMenuPage {}
}
Component {
id: chatInfoToolBarComponent
StatusChatInfoToolBarPage {}
}
Component {
id: statusModalComponent
Popups {}
}
Component {
id: statusTabSwitchesComponent
StatusTabSwitchPage {}
}
Component {
id: settingsComponent
StatusExpandableSettingsItemPage{}
}
Component {
id: notificationComponent
StatusMacNotificationPage {}
}
Component {
id: demoAppCmp
@@ -440,8 +423,7 @@ StatusWindow {
}
DemoApp {
id: demoApp
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.centerIn: parent
}
DropShadow {
anchors.fill: demoApp
@@ -493,4 +475,11 @@ StatusWindow {
rootWindow.toggleFullScreen()
}
}
Settings {
id: storeSettings
property string selected: ""
property bool lightTheme: true
property bool fillPage: false
}
}
@@ -2,53 +2,62 @@ import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import Sandbox 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
import Sandbox 0.1
Column {
spacing: 8
StatusAccountSelector {
id: accountSelector
accounts: ListModel {
ListElement {
name: "Pascal"
address: "0x1234567891011"
iconColor: "red"
balance: "0"
path: ""
color: "red"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "1199.02"
assets: []
fiatBalance: "1199.02"
}
ListElement {
name: "Boris"
address: "0x123"
iconColor: "red"
balance: "0"
path: ""
color: "red"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "0"
assets: []
fiatBalance: "0"
}
ListElement {
name: "Alexandra"
address: "0x123"
iconColor: "yellow"
balance: "0"
path: ""
color: "yellow"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "0"
assets: []
fiatBalance: "0"
}
ListElement {
name: "Khushboo"
address: "0x123"
iconColor: "blue"
balance: "0"
path: ""
color: "blue"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "0"
assets: []
fiatBalance: "0"
}
}
}
@@ -13,22 +13,26 @@ Column {
spacing: 8
StatusAssetSelector {
getCurrencyBalanceString: function (currencyBalance) {
return currencyBalance.toFixed(2) + " USD"
}
tokenAssetSourceFn: function (symbol) {
return "../../assets/img/icons/snt.svg"
}
assets: ListModel {
ListElement {
address: "0x1234"
name: "Status Network Token"
value: "20"
balance: "20"
symbol: "SNT"
fiatBalance: "9992.01"
fiatBalanceDisplay: "9992.01"
currencyBalance: 9992.01
}
ListElement {
address: "0x1234"
name: "DAI Token"
value: "20"
balance: "15"
symbol: "DAI"
fiatBalance: "20"
fiatBalanceDisplay: "20"
currencyBalance: 20.00001
}
}
}
@@ -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
}
}
@@ -0,0 +1,94 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import QtGraphicalEffects 1.14
Item {
id: root
implicitWidth: mainLayout.implicitWidth
implicitHeight: mainLayout.implicitHeight
property var testControls: [ctrl1, ctrl2, ctrl3]
property bool globalStylePreferRound: true
ColumnLayout {
id: mainLayout
anchors.fill: parent
RowLayout {
ColumnLayout {
Text {
text: `AR: ${ctrl1.aspectRatio.toFixed(2)}`
}
StatusImageCropPanel {
id: ctrl1
Layout.fillWidth: true
Layout.fillHeight: true
source: "qrc:/demoapp/data/logo-test-image.png"
windowStyle: globalStylePreferRound ? StatusImageCrop.WindowStyle.Rounded : StatusImageCrop.WindowStyle.Rectangular
}
Text {
text: `AR: ${ctrl2.aspectRatio.toFixed(2)}`
}
StatusImageCropPanel {
id: ctrl2
Layout.fillWidth: true
Layout.fillHeight: true
source: "qrc:/demoapp/data/logo-test-image.png"
windowStyle: globalStylePreferRound ? StatusImageCrop.WindowStyle.Rectangular : StatusImageCrop.WindowStyle.Rounded
aspectRatio: 16/9
enableCheckers: true
}
}
ColumnLayout {
Text {
text: `AR: ${ctrl3.aspectRatio.toFixed(2)}`
}
StatusImageCropPanel {
id: ctrl3
Layout.fillWidth: true
Layout.fillHeight: true
source: "qrc:/demoapp/data/logo-test-image.png"
windowStyle: globalStylePreferRound ? StatusImageCrop.WindowStyle.Rounded : StatusImageCrop.WindowStyle.Rectangular
aspectRatio: 0.8
}
}
}
Shortcut {
sequence: StandardKey.ZoomIn
onActivated: {
for(let i in testControls) {
const c = testControls[i]
c.setCropRect(ctrl1.inflateRectBy(c.cropRect, -0.05))
}
}
}
Shortcut {
sequence: StandardKey.ZoomOut
onActivated: {
for(let i in testControls) {
const c = testControls[i]
c.setCropRect(ctrl1.inflateRectBy(c.cropRect, 0.05))
}
}
}
Shortcut {
sequences: ["Ctrl+W"]
onActivated: globalStylePreferRound = !globalStylePreferRound
}
}
}
@@ -57,11 +57,38 @@ Column {
input.clearable: true
}
Item {
implicitWidth: 480
implicitHeight: 82
z: 100000
StatusSeedPhraseInput {
id: statusSeedInput
anchors.left: parent.left
anchors.right: parent.right
height: parent.height
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
errorMessage: "Error message"
input.clearable: true
input.valid: false
input.placeholderText: "Placeholder"
@@ -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
}
}
+81
View File
@@ -0,0 +1,81 @@
import QtQuick 2.0
import QtQuick.Layouts 1.14
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core 0.1
import "../demoapp/data" 1.0
GridLayout {
id: root
columns: 1
rowSpacing: 150
GridLayout {
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
rows: 4
columns: 2
rowSpacing: 170
columnSpacing: 150
z: 100
StatusListPicker {
id: languagePicker
z: 100
inputList: Models.languagePickerModel
placeholderSearchText: qsTr("Search Languages")
menuAlignment: StatusListPicker.MenuAlignment.Left
}
StatusListPicker {
id: languagePicker2
z: 100
inputList: Models.languageNoImagePickerModel
placeholderSearchText: qsTr("Search Languages")
menuAlignment: StatusListPicker.MenuAlignment.Center
}
StatusListPicker {
id: currencyPicker
inputList: Models.currencyPickerModel
placeholderSearchText: qsTr("Search Currencies")
multiSelection: true
}
StatusListPicker {
id: currencyPicker2
inputList: Models.currencyPickerModel2
placeholderSearchText: qsTr("Search Currencies")
multiSelection: true
printSymbol: true
enableSelectableItem: false
}
}
StatusBaseText {
id: pageDesc
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
height: 100
width: 500
text: "4 different configurations for the `StatusListPicker` component:\n
* Single selection. \n
* Single selection but dynamically changed to multiple selection (model provides multiple selected items).\n
* Multiple selection.\n
* Multiple selection and displayed name is the symbol + shortName\n"
color: Theme.palette.baseColor1
font.pixelSize: 15
}
// Outsite area
MouseArea {
height: root.height
width: root.width
onClicked: {
languagePicker.close()
languagePicker2.close()
currencyPicker.close()
currencyPicker2.close()
}
}
}
@@ -0,0 +1,38 @@
import QtQuick.Layouts 1.14
import StatusQ.Controls 0.1
GridLayout {
columns: 1
columnSpacing: 5
rowSpacing: 5
StatusPasswordStrengthIndicator {
id: veryweakPw
strength: StatusPasswordStrengthIndicator.Strength.VeryWeak
value: 0.75
}
StatusPasswordStrengthIndicator {
id: weakPw
strength: StatusPasswordStrengthIndicator.Strength.Weak
value: 0.5
}
StatusPasswordStrengthIndicator {
id: sosoPw
strength: StatusPasswordStrengthIndicator.Strength.SoSo
value: 0.25
}
StatusPasswordStrengthIndicator {
id: goodPw
strength: StatusPasswordStrengthIndicator.Strength.Good
value: 1
}
StatusPasswordStrengthIndicator {
id: greatPw
strength: StatusPasswordStrengthIndicator.Strength.Great
value: 0.3
}
}
+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
}
}
+27
View File
@@ -0,0 +1,27 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import Sandbox 0.1
Column {
spacing: 8
StatusTabBar {
StatusTabButton {
width: implicitWidth
text: "Button 1"
}
StatusTabButton {
width: implicitWidth
text: "Button 2"
}
StatusTabButton {
width: implicitWidth
text: "Button 3"
badge.value: 42
}
}
}
+56
View File
@@ -0,0 +1,56 @@
import QtQuick 2.14
import StatusQ.Components 0.1
Item {
id: root
anchors.fill: parent
property ListModel asortedContacts: ListModel {
ListElement {
publicId: "0x0"
name: "Maria"
icon: ""
isIdenticon: false
onlineStatus: 3
}
ListElement {
publicId: "0x1"
name: "James"
icon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
isIdenticon: false
onlineStatus: 1
}
ListElement {
publicId: "0x2"
name: "Paul"
icon: ""
isIdenticon: false
onlineStatus: 2
}
ListElement {
publicId: "0x3"
name: "Tracy"
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
isIdenticon: true
onlineStatus: 3
}
ListElement {
publicId: "0x4"
name: "Nick"
icon: ""
isIdenticon: false
onlineStatus: 3
}
}
StatusTagSelector {
id: tagSelector
width: 650
height: 44
anchors.centerIn: parent
namesModel: root.asortedContacts
toLabelText: qsTr("To: ")
warningText: qsTr("USER LIMIT REACHED")
}
}
+41
View File
@@ -0,0 +1,41 @@
import QtQuick 2.14
import StatusQ.Components 0.1
Item {
id: root
anchors.fill: parent
Column {
id: toastArea
anchors.centerIn: parent
spacing: 8
Repeater {
id: toastRepeater
width: parent.width
height: childrenRect.height
model: [
{"title":"anna.eth wants to verify your identity", "subTitle":"Provide the code in the letter I sent to you on February 1st.", "icon":"contact", "loading":false, "type":0,"url":"", "duration":0},
{"title":"Verification Request Sent", "subTitle":"", "icon":"checkmark-circle", "loading":false, "type":1,"url":"", "duration":4000},
{"title":"Collectible is being minted...", "subTitle":"View on Etherscan", "icon":"", "loading":true, "type":0,"url":"http://google.com", "duration":0},
{"title":"Contact request sent", "subTitle":"", "icon":"checkmark-circle", "loading":false, "type":1,"url":"", "duration":4000},
{"title":"Test User", "subTitle":"Hello message...", "icon":"", "loading":false, "type":0,"url":"", "duration":4000}
]
delegate: StatusToastMessage {
primaryText: modelData.title
secondaryText: modelData.subTitle
icon.name: modelData.icon
loading: modelData.loading
type: modelData.type
linkUrl: modelData.url
duration: modelData.duration
onLinkActivated: {
Qt.openUrlExternally(link);
}
onClose: {
console.warn("toast closed: ", modelData.title)
}
}
}
}
}
@@ -12,6 +12,6 @@ Column {
spacing: 8
StatusWalletColorSelect {
model: Theme.palette.accountColors
model: Theme.palette.userCustomizationColors
}
}
+100
View File
@@ -0,0 +1,100 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
Item {
id: root
width: 800
height: 100
//Simulate animation between steps
property bool stepsCompleted: false
function reset() {
for (var i = 0; i < stepsListModel.count; i++) {
stepsListModel.setProperty(i, "loading", false);
stepsListModel.setProperty(i, "stepCompleted", false);
step1.loadingTime = 0;
step2.loadingTime = 0;
root.stepsCompleted = false;
}
}
ListModel {
id: stepsListModel
ListElement {description:"Send Request"; loadingTime: 0; stepCompleted: false}
ListElement {description:"Receive Response"; loadingTime: 0; stepCompleted: false}
ListElement {description:"Confirm Identity"; loadingTime: 0; stepCompleted: false}
}
Shortcut {
sequence: "Ctrl+R"
onActivated: {
if (!root.stepsCompleted) {
animate.running = true;
} else {
root.reset();
}
}
}
StatusBaseText {
id: indicLabel
anchors.horizontalCenter: parent.horizontalCenter
color: Theme.palette.directColor1
text: "Press Ctrl+R to run the animation"
font.pixelSize: 17
}
SequentialAnimation {
id: animate
ScriptAction {
id: step1
property int loadingTime: 0
Behavior on loadingTime { NumberAnimation { duration: 2000 }}
onLoadingTimeChanged: {
stepsListModel.setProperty(1, "loadingTime", step1.loadingTime);
}
script: {
step1.loadingTime = 2000;
stepsListModel.setProperty(0, "loadingTime", step1.loadingTime);
stepsListModel.setProperty(0, "stepCompleted", true);
}
}
PauseAnimation {
duration: 2100
}
ScriptAction {
id: step2
property int loadingTime: 0
Behavior on loadingTime { NumberAnimation { duration: 2000 } }
onLoadingTimeChanged: {
stepsListModel.setProperty(2, "loadingTime", step2.loadingTime);
}
script: {
step2.loadingTime = 2000;
stepsListModel.setProperty(1, "stepCompleted", true);
}
}
PauseAnimation {
duration: 2100
}
ScriptAction {
script: {
stepsListModel.setProperty(2, "stepCompleted", true);
root.stepsCompleted = true;
}
}
}
//simulation code
StatusWizardStepper {
id: wizardStepper
width: (parent.width - 50)
anchors.top: indicLabel.bottom
anchors.topMargin: 16
anchors.horizontalCenter: parent.horizontalCenter
stepsModel: stepsListModel
}
}
+40 -11
View File
@@ -1,18 +1,47 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>Controls.qml</file>
<file>Icons.qml</file>
<file>Others.qml</file>
<file>Buttons.qml</file>
<file>pages/StatusAccountSelectorPage.qml</file>
<file>pages/StatusAddressPage.qml</file>
<file>pages/StatusAssetSelectorPage.qml</file>
<file>pages/StatusChatCommandButtonPage.qml</file>
<file>pages/StatusChatInfoToolBarPage.qml</file>
<file>pages/StatusColorSelectorPage.qml</file>
<file>pages/StatusExpandableSettingsItemPage.qml</file>
<file>pages/StatusInputPage.qml</file>
<file>pages/StatusMacNotificationPage.qml</file>
<file>pages/StatusPopupMenuPage.qml</file>
<file>pages/StatusSelectPage.qml</file>
<file>pages/StatusTabBarIconButtonPage.qml</file>
<file>pages/StatusTabSwitchPage.qml</file>
<file>pages/StatusWalletColorButtonPage.qml</file>
<file>pages/StatusWalletColorSelectPage.qml</file>
<file>pages/StatusPasswordStrengthIndicatorPage.qml</file>
<file>controls/Buttons.qml</file>
<file>controls/Controls.qml</file>
<file>controls/Icons.qml</file>
<file>controls/Layout.qml</file>
<file>controls/ListItems.qml</file>
<file>controls/Others.qml</file>
<file>controls/Popups.qml</file>
<file>demoapp/ChatChannelView.qml</file>
<file>demoapp/CreateChatView.qml</file>
<file>demoapp/DemoCommunityDetailModal.qml</file>
<file>demoapp/DemoContactRequestsModal.qml</file>
<file>demoapp/StatusAppChatView.qml</file>
<file>demoapp/StatusAppCommunityView.qml</file>
<file>demoapp/StatusAppProfileSettingsView.qml</file>
<file>demoapp/data/Models.qml</file>
<file>demoapp/data/qmldir</file>
<file>demoapp/data/logo-test-image.png</file>
<file>DemoApp.qml</file>
<file>ListItems.qml</file>
<file>StatusChatInfoToolBarPage.qml</file>
<file>StatusPopupMenuPage.qml</file>
<file>StatusInputPage.qml</file>
<file>ThemeSwitch.qml</file>
<file>Layout.qml</file>
<file>Popups.qml</file>
<file>StatusExpandableSettingsItemPage.qml</file>
<file>pages/StatusColorSelectorGridPage.qml</file>
<file>pages/StatusListPickerPage.qml</file>
<file>pages/StatusPinInputPage.qml</file>
<file>pages/StatusTagSelectorPage.qml</file>
<file>pages/StatusToastMessagePage.qml</file>
<file>pages/StatusWizardStepperPage.qml</file>
<file>pages/StatusTabBarButtonPage.qml</file>
</qresource>
</RCC>
+10 -9
View File
@@ -15,13 +15,16 @@ SOURCES += \
handler.cpp \
main.cpp \
sandboxapp.cpp \
spellchecker.cpp
spellchecker.cpp \
!macx {
SOURCES += statuswindow.cpp
}
TARGET = sandboxapp
DESTDIR = $$PWD/bin
DESTDIR = $$PWD/bin
macx {
CONFIG -= app_bundle
@@ -38,6 +41,12 @@ macx {
DEFINES += USE_HUNSPELL
message("hunspell exists in /usr/local/lib")
}
copydata.commands = $(COPY_DIR) $$PWD/dictionaries $$DESTDIR
first.depends = $(first) copydata
export(first.depends)
export(copydata.commands)
QMAKE_EXTRA_TARGETS += first copydata
}
ios {
@@ -54,14 +63,6 @@ ios {
RESOURCES += qml.qrc \
$$PWD/../statusq.qrc
DESTDIR = $$PWD/bin
copydata.commands = $(COPY_DIR) $$PWD/dictionaries $$DESTDIR
first.depends = $(first) copydata
export(first.depends)
export(copydata.commands)
QMAKE_EXTRA_TARGETS += first copydata
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
+1 -1
View File
@@ -20,7 +20,7 @@ void SandboxApp::startEngine()
qmlRegisterType<SpellChecker>("Sandbox", 0, 1, "Spellchecker");
#ifdef QT_DEBUG
const QUrl url(applicationDirPath() + "/../main.qml");
const QUrl url = QUrl::fromLocalFile(applicationDirPath() + "/../main.qml");
#else
const QUrl url(QStringLiteral("qrc:/main.qml"));
#endif
+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
+1 -1
View File
@@ -32,7 +32,7 @@ Rectangle {
anchors.centerIn: parent
text: {
if (statusBadge.value > 99) {
return "99+";
return qsTr("99+");
}
return statusBadge.value;
}
@@ -27,7 +27,6 @@ Item {
id: statusChatInfoButton
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 5
anchors.right: (implicitWidth > parent.width - 50) ? statusMenuButton.left : undefined
anchors.rightMargin: 5
type: StatusChatInfoButton.Type.OneToOneChat
@@ -37,7 +36,6 @@ Item {
StatusRoundButton {
id: statusMenuButton
anchors.right: parent.right
anchors.rightMargin: 8
anchors.verticalCenter: parent.verticalCenter
visible: popupMenuSlot.active
@@ -104,5 +102,4 @@ Item {
}
}
}
}
+26 -36
View File
@@ -15,19 +15,17 @@ Column {
width: 288
property string categoryId: ""
property string selectedChatId: ""
property alias chatListItems: delegateModel
property var model: null
property bool draggableItems: false
property bool highlightItem: true
property alias statusChatListItems: statusChatListItems
property Component popupMenu
property var filterFn
property var profileImageFn
property var chatNameFn
signal chatItemSelected(string id)
signal chatItemSelected(string categoryId, string id)
signal chatItemUnmuted(string id)
signal chatItemReordered(string id, int from, int to)
@@ -39,17 +37,16 @@ Column {
DelegateModel {
id: delegateModel
model: statusChatList.model
delegate: Item {
id: draggable
width: statusChatListItem.width
height: statusChatListItem.height
property alias chatListItem: statusChatListItem
visible: {
if (!!statusChatList.filterFn) {
return statusChatList.filterFn(model, statusChatList.categoryId)
return statusChatList.filterFn(model)
}
return true
}
@@ -94,36 +91,30 @@ Column {
}
StatusChatListItem {
id: statusChatListItem
property string profileImage: ""
opacity: dragSensor.active ? 0.0 : 1.0
Component.onCompleted: {
if (typeof statusChatList.profileImageFn === "function") {
profileImage = statusChatList.profileImageFn(model.chatId || model.id) || ""
}
}
originalOrder: model.position
chatId: model.chatId || model.id
categoryId: model.categoryId || ""
name: !!statusChatList.chatNameFn ? statusChatList.chatNameFn(model) : model.name
type: model.chatType
muted: !!model.muted
hasUnreadMessages: !!model.hasUnreadMessages || model.unviewedMessagesCount > 0
hasMention: model.mentionsCount > 0
badge.value: model.chatType === StatusChatListItem.Type.OneToOneChat ?
model.unviewedMessagesCount || 0 :
model.mentionsCount || 0
selected: (model.chatId || model.id) === statusChatList.selectedChatId
chatId: model.itemId
categoryId: model.parentItemId? model.parentItemId : ""
name: model.name
type: !!model.type ? model.type : StatusChatListItem.Type.CommunityChat
muted: model.muted
hasUnreadMessages: model.hasUnreadMessages
notificationsCount: model.notificationsCount
highlightWhenCreated: !!model.highlight
selected: (model.active && statusChatList.highlightItem)
icon.color: model.color || ""
image.isIdenticon: !!!profileImage && !!!model.identityImage && !!model.identicon
image.source: profileImage || model.identityImage || model.identicon || ""
icon.emoji: model.emoji
icon.color: !!model.color ? model.color : Theme.palette.userCustomizationColors[model.colorId]
image.isIdenticon: false
image.source: model.icon
ringSettings.ringSpecModel: model.colorHash
sensor.cursorShape: dragSensor.cursorShape
onClicked: {
highlightWhenCreated = false
if (mouse.button === Qt.RightButton && !!statusChatList.popupMenu) {
statusChatListItem.highlighted = true
@@ -132,7 +123,7 @@ Column {
popupMenuSlot.item.openHandler = function () {
if (!!originalOpenHandler) {
originalOpenHandler((model.chatId || model.id))
originalOpenHandler(model.itemId)
}
}
@@ -152,10 +143,10 @@ Column {
return
}
if (!statusChatListItem.selected) {
statusChatList.chatItemSelected(model.chatId || model.id)
statusChatList.chatItemSelected(model.parentItemId, model.itemId)
}
}
onUnmute: statusChatList.chatItemUnmuted(model.chatId || model.id)
onUnmute: statusChatList.chatItemUnmuted(model.itemId)
}
}
@@ -204,9 +195,8 @@ Column {
type: draggable.chatListItem.type
muted: draggable.chatListItem.muted
dragged: true
hasUnreadMessages: draggable.chatListItem.hasUnreadMessages
hasMention: draggable.chatListItem.hasMention
badge.value: draggable.chatListItem.badge.value
hasUnreadMessages: model.hasUnreadMessages
notificationsCount: model.notificationsCount
selected: draggable.chatListItem.selected
icon.color: draggable.chatListItem.icon.color
@@ -14,17 +14,15 @@ Item {
implicitWidth: chatListsAndCategories.width
property StatusTooltipSettings categoryAddButtonToolTip: StatusTooltipSettings {
text: "Add channel inside category"
text: qsTr("Add channel inside category")
}
property StatusTooltipSettings categoryMenuButtonToolTip: StatusTooltipSettings {
text: "More"
text: qsTr("More")
}
property string selectedChatId: ""
property var model: []
property bool showCategoryActionButtons: false
property bool showPopupMenu: true
property alias chatList: statusChatList.chatListItems
property alias categoryList: delegateModel
property alias sensor: sensor
property bool draggableItems: false
property bool draggableCategories: false
@@ -36,7 +34,7 @@ Item {
property Component chatListPopupMenu
property Component popupMenu
signal chatItemSelected(string id)
signal chatItemSelected(string categoryId, string id)
signal chatItemUnmuted(string id)
signal chatItemReordered(string categoryId, string chatId, int from, int to)
signal chatListCategoryReordered(string categoryId, int from, int to)
@@ -70,27 +68,25 @@ Item {
StatusChatList {
id: statusChatList
anchors.horizontalCenter: parent.horizontalCenter
visible: chatListItems.count > 0
selectedChatId: statusChatListAndCategories.selectedChatId
onChatItemSelected: statusChatListAndCategories.chatItemSelected(id)
visible: statusChatList.model.count > 0
onChatItemSelected: statusChatListAndCategories.chatItemSelected(categoryId, id)
onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id)
onChatItemReordered: statusChatListAndCategories.chatItemReordered(categoryId, id, from, to)
draggableItems: statusChatListAndCategories.draggableItems
model: statusChatListAndCategories.model
filterFn: function (model) {
return !!!model.categoryId
return !model.isCategory
}
popupMenu: statusChatListAndCategories.chatListPopupMenu
}
DelegateModel {
id: delegateModel
model: statusChatListAndCategories.model
delegate: Item {
id: draggable
width: statusChatListCategory.width
height: statusChatListCategory.height
property alias chatListCategory: statusChatListCategory
StatusChatListCategory {
@@ -99,7 +95,7 @@ Item {
property bool dragActive: false
property real startY: 0
property real startX: 0
opacity: dragActive ? 0.0 : 1.0
dragSensor.drag.target: draggedListCategoryLoader.item
@@ -136,16 +132,15 @@ Item {
menuButton.tooltip: statusChatListAndCategories.categoryMenuButtonToolTip
originalOrder: model.position
categoryId: model.categoryId
categoryId: model.itemId
name: model.name
showActionButtons: statusChatListAndCategories.showCategoryActionButtons
addButton.onClicked: statusChatListAndCategories.categoryAddButtonClicked(model.categoryId)
addButton.onClicked: statusChatListAndCategories.categoryAddButtonClicked(model.itemId)
chatList.chatListItems.model: statusChatListAndCategories.chatList.model
chatList.selectedChatId: statusChatListAndCategories.selectedChatId
chatList.onChatItemSelected: statusChatListAndCategories.chatItemSelected(id)
chatList.model: model.subItems
chatList.onChatItemSelected: statusChatListAndCategories.chatItemSelected(categoryId, id)
chatList.onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id)
chatList.onChatItemReordered: statusChatListAndCategories.chatItemReordered(model.categoryId, id, from, to)
chatList.onChatItemReordered: statusChatListAndCategories.chatItemReordered(model.itemId, id, from, to)
chatList.draggableItems: statusChatListAndCategories.draggableItems
popupMenu: statusChatListAndCategories.categoryPopupMenu
@@ -154,7 +149,7 @@ Item {
// Used to set the initial value of "opened" when the
// model is bound/changed.
opened: {
let openedState = statusChatListAndCategories.openedCategoryState[model.categoryId]
let openedState = statusChatListAndCategories.openedCategoryState[model.itemId]
return openedState !== undefined ? openedState : true // defaults to open
}
@@ -163,7 +158,7 @@ Item {
// as the state would be lost each time the model is
// changed.
onOpenedChanged: {
statusChatListAndCategories.openedCategoryState[model.categoryId] = statusChatListCategory.opened
statusChatListAndCategories.openedCategoryState[model.itemId] = statusChatListCategory.opened
}
}
@@ -212,8 +207,7 @@ Item {
name: draggable.chatListCategory.name
showActionButtons: draggable.chatListCategory.showActionButtons
chatList.chatListItems.model: draggable.chatListCategory.chatList.chatListItems.model
chatList.selectedChatId: draggable.chatListCategory.chatList.selectedChatId
chatList.model: draggable.chatListCategory.chatList.model
}
}
}
@@ -35,11 +35,11 @@ Column {
StatusChatListCategoryItem {
id: statusChatListCategoryItem
title: statusChatListCategory.name
visible: model.isCategory
opened: statusChatListCategory.opened
sensor.pressAndHoldInterval: 150
showMenuButton: showActionButtons && !!statusChatListCategory.popupMenu
highlighted: statusChatListCategory.dragged
sensor.onClicked: {
if (sensor.enabled) {
@@ -48,7 +48,6 @@ Column {
popupMenuSlot.item.popup(mouse.x + 4, mouse.y + 6);
return
}
statusChatListCategory.opened = !opened;
}
}
onTitleClicked: statusChatListCategory.opened = !opened
@@ -68,7 +67,7 @@ Column {
visible: statusChatListCategory.opened
categoryId: statusChatListCategory.categoryId
filterFn: function (model) {
return !!model.categoryId && model.categoryId == statusChatList.categoryId
return !!model.parentItemId && model.parentItemId === statusChatList.categoryId
}
popupMenu: statusChatListCategory.chatListPopupMenu
@@ -39,21 +39,21 @@ StatusListItem {
id: addButton
icon.name: "add"
icon.width: 20
visible: statusChatListCategoryItem.showAddButton &&
visible: statusChatListCategoryItem.showAddButton &&
(statusChatListCategoryItem.highlighted ||
statusChatListCategoryItem.sensor.containsMouse)
onClicked: statusChatListCategoryItem.addButtonClicked(mouse)
tooltip.text: "Add channel inside category"
tooltip.text: qsTr("Add channel inside category")
},
StatusChatListCategoryItemButton {
id: menuButton
icon.name: "more"
icon.width: 21
visible: statusChatListCategoryItem.showMenuButton &&
visible: statusChatListCategoryItem.showMenuButton &&
(statusChatListCategoryItem.highlighted ||
statusChatListCategoryItem.sensor.containsMouse)
onClicked: statusChatListCategoryItem.menuButtonClicked(mouse)
tooltip.text: "More"
tooltip.text: qsTr("More")
},
StatusChatListCategoryItemButton {
id: toggleButton
+45 -35
View File
@@ -5,11 +5,12 @@ 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
Rectangle {
id: statusChatListItem
id: root
objectName: "chatItem"
property int originalOrder: -1
@@ -18,7 +19,7 @@ Rectangle {
property string name: ""
property alias badge: statusBadge
property bool hasUnreadMessages: false
property bool hasMention: false
property int notificationsCount: 0
property bool muted: false
property StatusImageSettings image: StatusImageSettings {
width: 24
@@ -28,10 +29,13 @@ Rectangle {
width: 24
height: 24
color: Theme.palette.miscColor5
letterSize: 15
emoji: ""
charactersLen: root.type === StatusChatListItem.Type.OneToOneChat ? 2 : 1
}
property alias ringSettings: identicon.ringSettings
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
@@ -58,7 +62,7 @@ Rectangle {
if (selected) {
return Theme.palette.statusChatListItem.selectedBackgroundColor
}
return sensor.containsMouse || highlighted ? Theme.palette.statusChatListItem.hoverBackgroundColor : Theme.palette.baseColor4
return hoverHander.hovered || highlighted ? Theme.palette.statusChatListItem.hoverBackgroundColor : Theme.palette.baseColor4
}
opacity: dragged ? 0.7 : 1
@@ -66,21 +70,24 @@ Rectangle {
MouseArea {
id: sensor
HoverHandler {
id: hoverHander
}
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled: true
onClicked: statusChatListItem.clicked(mouse)
onClicked: root.clicked(mouse)
StatusSmartIdenticon {
id: identicon
anchors.left: parent.left
anchors.leftMargin: 8
anchors.verticalCenter: parent.verticalCenter
image: statusChatListItem.image
icon: statusChatListItem.icon
name: statusChatListItem.name
image: root.image
icon: root.icon
name: root.name
}
StatusIcon {
@@ -90,21 +97,21 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
width: 14
visible: statusChatListItem.type !== StatusChatListItem.Type.OneToOneChat
visible: root.type !== StatusChatListItem.Type.OneToOneChat
opacity: {
if (statusChatListItem.muted && !sensor.containsMouse && !statusChatListItem.highlighted) {
if (root.muted && !hoverHander.hovered && !root.highlighted) {
return 0.4
}
return statusChatListItem.hasMention ||
statusChatListItem.hasUnreadMessages ||
statusChatListItem.selected ||
statusChatListItem.highlighted ||
return root.hasUnreadMessages ||
root.notificationsCount > 0 ||
root.selected ||
root.highlighted ||
statusBadge.visible ||
sensor.containsMouse ? 1.0 : 0.7
hoverHander.hovered ? 1.0 : 0.7
}
icon: {
switch (statusChatListItem.type) {
switch (root.type) {
case StatusChatListItem.Type.PublicCat:
return Theme.palette.name == "light" ? "tiny/public-chat" : "tiny/public-chat-white"
break;
@@ -129,25 +136,27 @@ Rectangle {
anchors.rightMargin: 6
anchors.verticalCenter: parent.verticalCenter
text: (statusChatListItem.type === StatusChatListItem.Type.PublicChat &&
!statusChatListItem.name.startsWith("#") ?
"#" + statusChatListItem.name :
statusChatListItem.name)
text: (root.type === StatusChatListItem.Type.PublicChat &&
!root.name.startsWith("#") ?
"#" + root.name :
root.name)
elide: Text.ElideRight
color: {
if (statusChatListItem.muted && !sensor.containsMouse && !statusChatListItem.highlighted) {
if (root.muted && !hoverHander.hovered && !root.highlighted) {
return Theme.palette.directColor5
}
return statusChatListItem.hasMention ||
statusChatListItem.hasUnreadMessages ||
statusChatListItem.selected ||
statusChatListItem.highlighted ||
sensor.containsMouse ||
return root.hasUnreadMessages ||
root.notificationsCount > 0 ||
root.selected ||
root.highlighted ||
root.highlightWhenCreated ||
hoverHander.hovered ||
statusBadge.visible ? Theme.palette.directColor1 : Theme.palette.directColor4
}
font.weight: !statusChatListItem.muted &&
(statusChatListItem.hasMention ||
statusChatListItem.hasUnreadMessages ||
font.weight: !root.muted &&
(root.hasUnreadMessages ||
root.notificationsCount > 0 ||
root.highlightWhenCreated ||
statusBadge.visible) ? Font.Bold : Font.Medium
font.pixelSize: 15
}
@@ -160,18 +169,18 @@ Rectangle {
width: 14
opacity: mutedIconSensor.containsMouse ? 1.0 : 0.2
icon: Theme.palette.name === "light" ? "tiny/muted" : "tiny/muted-white"
visible: statusChatListItem.muted
visible: root.muted
MouseArea {
id: mutedIconSensor
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: statusChatListItem.unmute()
onClicked: root.unmute()
}
StatusToolTip {
text: "Unmute"
text: qsTr("Unmute")
visible: mutedIconSensor.containsMouse
}
}
@@ -183,10 +192,11 @@ Rectangle {
anchors.right: parent.right
anchors.rightMargin: 8
color: statusChatListItem.muted ? Theme.palette.primaryColor2 : Theme.palette.primaryColor1
color: root.muted ? Theme.palette.primaryColor2 : Theme.palette.primaryColor1
border.width: 4
border.color: color
visible: statusBadge.value > 0
value: root.notificationsCount
visible: root.notificationsCount > 0
}
}
}
+23 -13
View File
@@ -58,7 +58,7 @@ Rectangle {
onClicked: statusChatToolBar.searchButtonClicked()
// initializing the tooltip
tooltip.text: "Search"
tooltip.text: qsTr("Search")
tooltip.orientation: StatusToolTip.Orientation.Bottom
tooltip.y: parent.height + 12
}
@@ -72,7 +72,7 @@ Rectangle {
onClicked: statusChatToolBar.membersButtonClicked()
// initializing the tooltip
tooltip.text: "Members"
tooltip.text: qsTr("Members")
tooltip.orientation: StatusToolTip.Orientation.Bottom
tooltip.y: parent.height + 12
}
@@ -87,12 +87,31 @@ Rectangle {
// initializing the tooltip
tooltip.visible: !!tooltip.text && menuButton.hovered && !popupMenuSlot.item.opened
tooltip.text: "More"
tooltip.text: qsTr("More")
tooltip.orientation: StatusToolTip.Orientation.Bottom
tooltip.y: parent.height + 12
property bool showMoreMenu: false
onClicked: {
menuButton.highlighted = true
let originalOpenHandler = popupMenuSlot.item.openHandler
let originalCloseHandler = popupMenuSlot.item.closeHandler
popupMenuSlot.item.openHandler = function () {
if (!!originalOpenHandler) {
originalOpenHandler()
}
}
popupMenuSlot.item.closeHandler = function () {
menuButton.highlighted = false
if (!!originalCloseHandler) {
originalCloseHandler()
}
}
popupMenuSlot.item.openHandler = originalOpenHandler
popupMenuSlot.item.popup(-popupMenuSlot.item.width + menuButton.width, menuButton.height + 4)
statusChatToolBar.menuButtonClicked()
}
@@ -100,15 +119,6 @@ Rectangle {
Loader {
id: popupMenuSlot
active: !!statusChatToolBar.popupMenu
onLoaded: {
popupMenuSlot.item.closeHandler = function () {
menuButton.highlighted = false
}
popupMenuSlot.item.openHandler = function () {
menuButton.highlighted = true
}
}
}
}
@@ -131,7 +141,7 @@ Rectangle {
type: StatusFlatRoundButton.Type.Secondary
// initializing the tooltip
tooltip.text: "Activity"
tooltip.text: qsTr("Activity")
tooltip.orientation: StatusToolTip.Orientation.Bottom
tooltip.y: parent.height + 12
@@ -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
}
}
+19
View File
@@ -0,0 +1,19 @@
import QtQuick 2.13
import StatusQ.Core 0.1
Image {
id: root
property string emojiId: ""
width: 14
height: 14
sourceSize.width: width
sourceSize.height: height
fillMode: Image.PreserveAspectFit
mipmap: true
antialiasing: true
source: emojiId ? `../../assets/twemoji/svg/${emojiId}.svg` : ""
}
+108 -84
View File
@@ -12,6 +12,7 @@ Rectangle {
property alias additionalText: additionalText.text
property alias button: button
property alias expandableComponent: expandableRegion.sourceComponent
property alias expandableItem: expandableRegion.item
property int type: StatusExpandableItem.Type.Primary
property bool expandable: true
@@ -58,111 +59,134 @@ Rectangle {
}
StatusSmartIdenticon {
id: identicon
Rectangle {
id: header
anchors.top: parent.top
anchors.topMargin: 25
anchors.left: parent.left
anchors.leftMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? 0 : 11
image: statusExpandableItem.image
icon: statusExpandableItem.icon
name: primaryText.text
active: (statusExpandableItem.type !== StatusExpandableItem.Type.Tertiary)
}
width: parent.width
height: 64
radius: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? 8 : 0
color: statusExpandableItem.type === StatusExpandableItem.Type.Secondary && sensor.containsMouse ? Theme.palette.baseColor2 : "transparent"
StatusBaseText {
id: primaryText
anchors.top: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ||
(statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ? parent.top : undefined
anchors.topMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ? 29 : 17
anchors.left: identicon.active ? identicon.right : parent.left
anchors.leftMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 10 : 16
StatusSmartIdenticon {
id: identicon
anchors.top: parent.top
anchors.topMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? 12.5 : 25
anchors.left: parent.left
anchors.leftMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? 16 : 11
image: statusExpandableItem.image
icon: statusExpandableItem.icon
name: primaryText.text
active: (statusExpandableItem.type !== StatusExpandableItem.Type.Tertiary)
}
anchors.verticalCenter: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? identicon.verticalCenter : undefined
StatusBaseText {
id: primaryText
anchors.top: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ||
(statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ? parent.top : undefined
anchors.topMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ? 29 : 17
anchors.left: identicon.active ? identicon.right : parent.left
anchors.leftMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 10 : 16
width: !!additionalText.text ? (button.visible ? parent.width - icon.background.width - button.width - additionalText.contentWidth - 110 :
parent.width - icon.background.width - additionalText.contentWidth - 110) :
(button.visible ? parent.width - icon.background.width - button.width - 70 :
parent.width - icon.background.width - 70)
anchors.verticalCenter: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? identicon.verticalCenter : undefined
font.weight: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? Font.Medium : Font.Normal
font.pixelSize: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 15 : 17
lineHeight: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 22 : 24
lineHeightMode: Text.FixedHeight
elide: Text.ElideRight
color: (statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ? Theme.palette.baseColor1 : Theme.palette.directColor1
}
width: !!additionalText.text ? (button.visible ? parent.width - icon.background.width - button.width - additionalText.contentWidth - 110 :
parent.width - icon.background.width - additionalText.contentWidth - 110) :
(button.visible ? parent.width - icon.background.width - button.width - 70 :
parent.width - icon.background.width - 70)
StatusBaseText {
id: secondaryText
anchors.top: primaryText.bottom
anchors.topMargin: 4
anchors.left: primaryText.left
anchors.right: primaryText.right
font.weight: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? Font.Medium : Font.Normal
font.pixelSize: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 15 : 17
lineHeight: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 22 : 24
lineHeightMode: Text.FixedHeight
elide: Text.ElideRight
color: (statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ? Theme.palette.baseColor1 : Theme.palette.directColor1
}
font.pixelSize: 15
lineHeight: 22
lineHeightMode: Text.FixedHeight
elide: Text.ElideRight
color: Theme.palette.directColor3
}
StatusBaseText {
id: secondaryText
anchors.top: primaryText.bottom
anchors.topMargin: 4
anchors.left: primaryText.left
anchors.right: primaryText.right
StatusBaseText {
id: additionalText
anchors.verticalCenter: primaryText.verticalCenter
anchors.verticalCenterOffset: 2
anchors.right: expandImage.left
anchors.rightMargin: 16
font.pixelSize: 15
lineHeight: 22
lineHeightMode: Text.FixedHeight
elide: Text.ElideRight
color: Theme.palette.directColor3
}
font.pixelSize: 15
lineHeight: 24
lineHeightMode: Text.FixedHeight
elide: Text.ElideRight
color: Theme.palette.baseColor1
}
StatusBaseText {
id: additionalText
anchors.verticalCenter: primaryText.verticalCenter
anchors.verticalCenterOffset: 2
anchors.right: expandImage.left
anchors.rightMargin: 16
StatusButton {
id: button
anchors.top: parent.top
anchors.topMargin: 19
anchors.right: parent.right
anchors.rightMargin: 16
visible: !!text
}
font.pixelSize: 15
lineHeight: 24
lineHeightMode: Text.FixedHeight
elide: Text.ElideRight
color: Theme.palette.baseColor1
}
StatusIcon {
id: expandImage
anchors.verticalCenter: (statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ?
primaryText.verticalCenter : identicon.verticalCenter
anchors.verticalCenterOffset:(statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ? -3 : -1
anchors.right: parent.right
anchors.rightMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 23 : 6
visible: expandable && !button.visible
color: (statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ?
Theme.palette.baseColor1 :
Theme.palette.directColor1
}
StatusButton {
id: button
anchors.top: parent.top
anchors.topMargin: 19
anchors.right: parent.right
anchors.rightMargin: 16
visible: !!text
}
MouseArea {
anchors.fill: parent
onClicked: {
if(expandable) {
expanded = !expanded
StatusIcon {
id: expandImage
anchors.verticalCenter: (statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ?
primaryText.verticalCenter : identicon.verticalCenter
anchors.verticalCenterOffset:(statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ? -3 : -1
anchors.right: parent.right
anchors.rightMargin: {
switch (statusExpandableItem.type) {
case StatusExpandableItem.Type.Primary:
return 23
break;
case StatusExpandableItem.Type.Secondary:
return 16
break;
default:
return 6
}
}
visible: expandable && !button.visible
color: (statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ?
Theme.palette.baseColor1 :
Theme.palette.directColor1
}
MouseArea {
id: sensor
anchors.fill: parent
onClicked: {
if(expandable) {
expanded = !expanded
}
}
cursorShape: Qt.PointingHandCursor
visible: !button.visible && expandable
hoverEnabled: true
}
cursorShape: Qt.PointingHandCursor
visible: !button.visible && expandable
}
Loader {
id: expandableRegion
anchors.top: !!secondaryText.text ? secondaryText.bottom: primaryText.bottom
anchors.top: header.bottom
anchors.topMargin: 16
anchors.left: parent.left
anchors.leftMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 48 : 0
anchors.right: parent.right
anchors.rightMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 16 : 0
active: false
visible: false
}
onExpandedChanged: {
@@ -179,13 +203,13 @@ Rectangle {
name: "EXPANDED"
PropertyChanges {target: expandImage; icon: "chevron-up"}
PropertyChanges {target: statusExpandableItem; height: 82 + expandableRegion.height + 22}
PropertyChanges {target: expandableRegion; active: true}
PropertyChanges {target: expandableRegion; visible: true}
},
State {
name: "COLLAPSED"
PropertyChanges {target: expandImage; icon: "chevron-down"}
PropertyChanges {target: statusExpandableItem; height: 82}
PropertyChanges {target: expandableRegion; active: false}
PropertyChanges {target: expandableRegion; visible: false}
}
]
@@ -0,0 +1,281 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
/*!
\qmltype StatusImageCropPanel
\inherits Item
\inqmlmodule StatusQ.Components
\since StatusQ.Components 0.1
\brief Draw a crop-window onto an image and allows manipulating the position of the crop-window. Inherits \l{https://doc.qt.io/qt-5/qml-qtquick-item.html}{Item}.
Adds mouse pan and zoom functionality on top of StatusImageCrop functionality. Also adds small
practical features and optimizes drawing by minimizing StatusImageCrop area
\sa StatusImageCrop for more details
Example of how to use it:
\qml
StatusImageCropPanel {
width: 400
height: 200
source: "qrc:/demoapp/data/logo-test-image.png"
windowStyle: StatusImageCrop.WindowStyle.Rectangular
Component.onCompleted: setCropRect(Qt.rect(10, 0, sourceSize.width - 20, sourceSize.height))
}
\endqml
For a list of components available see StatusQ.
*/
Item {
id: root
implicitWidth: mainLayout.implicitWidth
implicitHeight: mainLayout.implicitHeight
/*!
\qmlproperty real StatusImageCrop::aspectRatio
Initial aspect-ratio of the crop-window
*/
property real aspectRatio: 1
/*!
\qmlproperty bool StatusImageCrop::interactive
If true allows user to interact with the image. Set to false for previewing existing crop-data
*/
property bool interactive: true
/*!
\qmlproperty bool StatusImageCrop::margins
Space to keep around the control borders and crop area
*/
property int margins: 10
/*!
\qmlproperty url StatusImageCropPanel::source
\sa StatusImageCrop::source
*/
/*required*/ property alias source: cropEditor.source
/*!
\qmlproperty WindowStyle StatusImageCropPanel::windowStyle
\sa StatusImageCrop::windowStyle
*/
property alias windowStyle: cropEditor.windowStyle
/*!
\qmlproperty int StatusImageCropPanel::radius
\sa StatusImageCrop::radius
*/
property alias radius: cropEditor.radius
/*!
\qmlproperty color StatusImageCropPanel::wallColor
\sa StatusImageCrop::wallColor
*/
property alias wallColor: cropEditor.wallColor
/*!
\qmlproperty real StatusImageCropPanel::wallTransparency
\sa StatusImageCrop::wallTransparency
*/
property alias wallTransparency: cropEditor.wallTransparency
/*!
\qmlproperty rect StatusImageCropPanel::cropRect
\sa StatusImageCrop::cropRect
*/
property alias cropRect: cropEditor.cropRect
/*!
\qmlproperty rect StatusImageCropPanel::cropRect
\sa StatusImageCrop::cropRect
*/
readonly property alias cropWindow: cropEditor.cropWindow
/*!
\qmlproperty real StatusImageCrop::scrollZoomFactor
How fast is image scaled (zoomed) when using mouse scroll
*/
property real scrollZoomFactor: 0.5
/*!
\qmlproperty bool StatusImageCropPanel::enableCheckers
Shows helper guiding checkers pattern where image is not covering
*/
property bool enableCheckers: root.interactive
/*!
\qmlproperty size StatusImageCropPanel::sourceSize
\sa StatusImageCrop::sourceSize
*/
property alias sourceSize: cropEditor.sourceSize
/*
\qmlmethod StatusImageCropPanel::setCropRect(rect)
\sa StatusImageCrop::cropRect
*/
function setCropRect(newRect) {
cropEditor.setCropRect(newRect)
aspectRatio = cropEditor.aspectRatio
}
QtObject {
id: d
function updateAspectRatio(newAR) {
// Keep width and adjust height
const eW = cropEditor.cropRect.width
const w = (eW <= 0) ? cropEditor.sourceSize.width : eW
const h = w/newAR
const c = (eW <= 0)
? Qt.point(cropEditor.sourceSize.width/2, cropEditor.sourceSize.height/2)
: Qt.point(cropEditor.cropRect.x + w/2, cropEditor.cropRect.y + cropEditor.cropRect.height/2)
const nR = Qt.rect(c.x - w/2, c.y-h/2, w, h)
cropEditor.setCropRect(nR)
}
}
Component.onCompleted: d.updateAspectRatio(root.aspectRatio)
onAspectRatioChanged: d.updateAspectRatio(root.aspectRatio)
onSourceSizeChanged: d.updateAspectRatio(root.aspectRatio)
ColumnLayout {
id: mainLayout
anchors.fill: parent
Item {
id: cropSpaceItem
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
Rectangle {
id: leftOverlay
anchors.left: parent.left
anchors.top: parent.top
anchors.right: cropEditor.left
anchors.bottom: parent.bottom
color: wallColor
opacity: wallTransparency
z: cropEditor.z + 1
}
Rectangle {
id: topOverlay
anchors.left: leftOverlay.right
anchors.top: parent.top
anchors.right: rightOverlay.left
anchors.bottom: cropEditor.top
color: wallColor
opacity: wallTransparency
z: cropEditor.z + 1
}
StatusImageCrop {
id: cropEditor
anchors.centerIn: parent
width: aspectRatio < cropSpaceItem.width/cropSpaceItem.height ? cropSpaceItem.height * aspectRatio : cropSpaceItem.width - root.margins * 2
height: aspectRatio < cropSpaceItem.width/cropSpaceItem.height ? cropSpaceItem.height - root.margins * 2 : cropSpaceItem.width / aspectRatio
}
Rectangle {
id: rightOverlay
anchors.left: cropEditor.right
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: parent.bottom
color: wallColor
opacity: wallTransparency
z: cropEditor.z + 1
}
Rectangle {
id: bottomOverlay
anchors.left: leftOverlay.right
anchors.top: cropEditor.bottom
anchors.right: rightOverlay.left
anchors.bottom: parent.bottom
color: wallColor
opacity: wallTransparency
z: cropEditor.z + 1
}
// Checkers
Canvas {
visible: root.enableCheckers
anchors.fill: parent
onPaint: {
var ctx = getContext("2d")
for(let xI = 0; xI < Math.ceil(width/10); xI++) {
for(let yI = 0; yI < Math.ceil(height/10); yI++) {
ctx.fillStyle = (xI % 2) === (yI % 2) ? "#FFFFFE" : "#DBDBDB"
ctx.fillRect(xI * 10, yI * 10, 10, 10)
}
}
}
z: cropEditor.z - 1
}
// Drag and zoom
MouseArea {
anchors.fill: parent
enabled: root.interactive
property var lastDragPoint: null
onReleased: lastDragPoint = null
onMouseXChanged: updateDrag(Qt.point(mouse.x, mouse.y))
onMouseYChanged: updateDrag(Qt.point(mouse.x, mouse.y))
onWheel: {
const delta = wheel.angleDelta.y / 120
cropEditor.setCropRect(cropEditor.getZoomRect(cropEditor.zoomScale + delta * root.scrollZoomFactor))
}
function moveRect(r /*rect*/, delta /*real*/) {
return Qt.rect(r.x + delta.x, r.y + delta.y, r.width, r.height)
}
function scaleSize(sz /*size*/, s /*size*/) {
return Qt.point(sz.width * s, sz.height * s)
}
function updateDrag(p) {
let delta = (lastDragPoint ? Qt.size(lastDragPoint.x - p.x, lastDragPoint.y - p.y) : Qt.size(0, 0))
delta = scaleSize(delta, 1/cropEditor.scrToImgScale)
cropEditor.setCropRect(moveRect(cropEditor.cropRect, delta))
lastDragPoint = p
}
}
}
RowLayout {
visible: root.interactive
StatusIcon {
icon: "remove-circle"
Layout.preferredWidth: 20
Layout.preferredHeight: 20
}
StatusSlider {
Layout.fillWidth: true
Layout.topMargin: 20
Layout.bottomMargin: 25
Layout.alignment: Qt.AlignVCenter
enabled: root.interactive
from: cropEditor.minZoomScale
to: cropEditor.maxZoomScale
value: cropEditor.zoomScale
live: false
onMoved: cropEditor.setCropRect(cropEditor.getZoomRect(valueAt(visualPosition)))
}
StatusIcon {
icon: "add-circle"
Layout.preferredWidth: 20
Layout.preferredHeight: 20
}
}
}
}
@@ -1,30 +1,60 @@
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: Emoji.size.small
property int letterSize: 21
property int charactersLen: 1
color: Theme.palette.miscColor5
width: 40
height: 40
radius: width / 2
StatusEmoji {
visible: root.emoji
anchors.centerIn: parent
width: Math.round(parent.width / 2)
height: Math.round(parent.height / 2)
emojiId: Emoji.iconId(root.emoji, root.emojiSize) || ""
}
StatusBaseText {
id: identiconText
text: ((statusLetterIdenticon.name.charAt(0) === "#")
|| (statusLetterIdenticon.name.charAt(0) === "@") ?
statusLetterIdenticon.name.charAt(1) : statusLetterIdenticon.name.charAt(0)).toUpperCase()
visible: !root.emoji
anchors.alignWhenCentered: false
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
width: parent.width
height: parent.height
font.weight: Font.Bold
font.pixelSize: statusLetterIdenticon.letterSize
color: Qt.rgba(255, 255, 255, 0.7)
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: root.letterSize
color: d.luminance(root.color) > 0.5 ? Qt.rgba(0, 0, 0, 0.5) : Qt.rgba(255, 255, 255, 0.7)
text: {
const shift = (root.name.charAt(0) === "#") ||
(root.name.charAt(0) === "@")
return root.name.substring(shift, shift + charactersLen).toUpperCase()
}
}
QtObject {
id: d
function luminance(color) {
let r = Math.pow(color.r, 2.2) * 0.2126
let g = Math.pow(color.g, 2.2) * 0.7151
let b = Math.pow(color.b, 2.2) * 0.0721
return r + g + b
}
}
}
+139 -56
View File
@@ -9,49 +9,32 @@ import StatusQ.Controls 0.1
Rectangle {
id: statusListItem
implicitWidth: 448
implicitHeight: Math.max(64, statusListItemTitleArea.height + 16)
enum Type {
Primary,
Secondary,
Danger
}
color: {
if (sensor.containsMouse) {
switch(type) {
case StatusListItem.Type.Primary:
return Theme.palette.baseColor2
case StatusListItem.Type.Secondary:
return Theme.palette.statusListItem.secondaryHoverBackgroundColor
case StatusListItem.Type.Danger:
return Theme.palette.dangerColor3
}
}
return Theme.palette.statusListItem.backgroundColor
}
radius: 8
property string itemId: ""
property string titleId: ""
property string title: ""
property string titleAsideText: ""
property string subTitle: ""
property string tertiaryTitle: ""
property alias badge: statusListItemBadge
property string label: ""
property real leftPadding: 16
property real rightPadding: 16
property bool enabled: true
property bool highlighted: false
property bool propagateTitleClicks: true
property int type: StatusListItem.Type.Primary
property list<Item> components
property var bottomModel: []
property Component bottomDelegate
property var tagsModel: []
property Component tagsDelegate
property StatusIconSettings icon: StatusIconSettings {
height: isLetterIdenticon ? 40 : 20
width: isLetterIdenticon ? 40 : 20
rotation: 0
isLetterIdenticon: false
letterSize: 21
charactersLen: 1
color: isLetterIdenticon ? background.color : type === StatusListItem.Type.Danger ?
Theme.palette.dangerColor1 : Theme.palette.primaryColor1
background: StatusIconBackgroundSettings {
@@ -73,23 +56,56 @@ Rectangle {
height: 40
isIdenticon: false
}
property string label: ""
property int type: StatusListItem.Type.Primary
property StatusIdenticonRingSettings ringSettings: StatusIdenticonRingSettings {
initalAngleRad: 0
ringPxSize: 1.5
distinctiveColors: Theme.palette.identiconRingColors
}
property alias sensor: sensor
property alias badge: statusListItemBadge
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 list<Item> components
property alias statusListItemTagsSlot: statusListItemTagsSlot
property alias statusListItemInlineTagsSlot: statusListItemTagsSlotInline
signal clicked(string itemId)
signal titleClicked(string titleId)
enum Type {
Primary,
Secondary,
Danger
}
implicitWidth: 448
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) {
case StatusListItem.Type.Primary:
return Theme.palette.baseColor2
case StatusListItem.Type.Secondary:
return Theme.palette.statusListItem.secondaryHoverBackgroundColor
case StatusListItem.Type.Danger:
return Theme.palette.dangerColor3
}
}
return Theme.palette.statusListItem.backgroundColor
}
radius: 8
onComponentsChanged: {
if (components.length) {
for (let idx in components) {
@@ -106,6 +122,7 @@ Rectangle {
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled: true
preventStealing: true
onClicked: {
statusListItem.clicked(statusListItem.itemId)
@@ -122,17 +139,29 @@ Rectangle {
name: statusListItem.title
active: statusListItem.icon.isLetterIdenticon ||
!!statusListItem.icon.name ||
!!statusListItem.image.source.toString()
!!statusListItem.image.source.toString() ||
!!statusListItem.icon.emoji
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 {
@@ -140,26 +169,39 @@ Rectangle {
text: statusListItem.title
font.pixelSize: 15
height: visible ? contentHeight : 0
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
elide: Text.ElideRight
anchors.left: parent.left
anchors.top: bottomModel.length === 0 ? undefined: parent.top
anchors.topMargin: bottomModel.length === 0 ? undefined : 20
width: Math.min(implicitWidth, parent.width)
color: {
if (!statusListItem.enabled) {
return Theme.palette.baseColor1
}
switch (statusListItem.type) {
case StatusListItem.Type.Primary:
return Theme.palette.directColor1
case StatusListItem.Type.Secondary:
return Theme.palette.primaryColor1
case StatusListItem.Type.Danger:
return Theme.palette.dangerColor1
}
if (!statusListItem.enabled) {
return Theme.palette.baseColor1
}
switch (statusListItem.type) {
case StatusListItem.Type.Primary:
return Theme.palette.directColor1
case StatusListItem.Type.Secondary:
return Theme.palette.primaryColor1
case StatusListItem.Type.Danger:
return Theme.palette.dangerColor1
}
}
StatusToolTip {
id: statusListItemTitleTooltip
text: statusListItemTitle.text
delay: 0
visible: statusListItemTitle.truncated && statusListItemTitleMouseArea.containsMouse
}
MouseArea {
id: statusListItemTitleMouseArea
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
@@ -172,12 +214,21 @@ Rectangle {
anchors.left: statusListItemTitle.right
anchors.leftMargin: 4
anchors.verticalCenter: statusListItemTitle.verticalCenter
anchors.top: bottomModel.length === 0 ? undefined: parent.top
anchors.topMargin: bottomModel.length === 0 ? undefined : 20
text: statusListItem.titleAsideText
font.pixelSize: 10
color: Theme.palette.baseColor1
visible: !!statusListItem.titleAsideText
}
Loader {
id: titleIconsRow
anchors.left: !statusListItem.titleAsideText ? statusListItemTitle.right : statusListItemTitleAsideText.right
anchors.verticalCenter: statusListItemTitle.verticalCenter
anchors.leftMargin: 4
}
StatusBaseText {
id: statusListItemSubTitle
anchors.top: statusListItemTitle.bottom
@@ -208,11 +259,42 @@ Rectangle {
width: contentItem.width
implicitHeight: visible ? 22 : 0
}
Row {
id: statusListItemTagsSlotInline
anchors.top: statusListItemTertiaryTitle.bottom
width: parent.width
spacing: 10
clip: true
Repeater {
model: tagsModel
delegate: tagsDelegate
}
}
}
Row {
id: statusListItemTagsSlot
anchors.topMargin: 16
anchors.top: iconOrImage.bottom
anchors.left: parent.left
anchors.leftMargin: 16
width: statusListItemBadge.width
spacing: 10
anchors.verticalCenter: parent.verticalCenter
Repeater {
model: bottomModel
delegate: bottomDelegate
}
}
StatusBaseText {
id: statusListItemLabel
anchors.verticalCenter: 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
@@ -222,12 +304,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()
}
}
}
}
}
+392
View File
@@ -0,0 +1,392 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtGraphicalEffects 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
/*!
\qmltype StatusListPicker
\inherits Item
\inqmlmodule StatusQ.Components
\since StatusQ.Components 0.1
\brief It is a combination of StatusPickerButton and a drop-down list component that provides a way of presenting a list of selectable options to the user. Inherits \l{https://doc.qt.io/qt-5/qml-qtquick-item.html}{Item}.
The \c StatusListPicker is populated with a data model. The data model is commonly a JavaScript array or a ListModel object.
StatusListPicker can be made as a single or multiple options picker by setting its StatusListPicker::multiSelection property properly or will be auto-set if the model contains / provides more than one selected items.
The StatusPickerButton text holds the text of the current item selected in the list picker. If there is more than one item selected, a string composed will be displayed.
The drop-down list incorporates a searcher by the following model roles: `name` or / and `shortName`.
NOTE: Make sure to set the appropriate z-index when instantiating the component in order to place it on top of your view in order to display the drop-down data properly.
Make sure to position the component inside its parent also when it is spanned in order to achieve a better user experience.
Example of how the component looks like:
\image status_list_picker.png
Example of how to use it:
\qml
StatusListPicker {
id: currencyPicker
inputList: Models.currencyPickerModel
searchText: qsTr("Search Language")
multiSelection: true
printSymbol: true
}
\endqml
For a list of components available see StatusQ.
*/
Item {
id: root
/*!
\qmlproperty string StatusListPicker::inputList
This property holds the data that will be populated in the list picker.
NOTE: This model property should not change so it is an in / out property where the selected role will be dynamically changed according to user actions.
Here an example of the model roles expected:
\qml
inputList: ListModel {
ListElement {
key: 0
name: "United States Dollar"
shortName: "USD"
symbol: "$"
imageSource: "../../assets/twemoji/26x26/1f4b4.png"
category: "fiat"
selected: true
}
ListElement {
key: 1
name: "British Pound"
shortName: "GBP"
symbol: "£"
imageSource: "../../assets/twemoji/26x26/1f4b5.png"
category: "fiat"
selected: false
}
}
\endqml
*/
property ListModel inputList: ListModel { }
/*!
\qmlproperty string StatusListPicker::searchText
This property holds the search text the searcher input displays by default.
*/
property string searchText: ""
/*!
\qmlproperty string StatusListPicker::placeholderSearchText
This property holds the placeholder text the searcher input displays by default.
*/
property string placeholderSearchText: qsTr("Search")
/*!
\qmlproperty string StatusListPicker::multiSelection
This property holds whether the list picker is a single or a multiple picker option by displaying a StatusRadioButton or StatusCheckBox instead.
*/
property bool multiSelection: false
/*!
\qmlproperty string StatusListPicker::printSymbol
This property holds whether the selected items will display a composition of the role `symbol` in the StatusPickerButton text or just only the role `shortName`.
*/
property bool printSymbol: false
/*!
\qmlproperty string StatusListPicker::maxPickerHeight
This property holds the maximum drop-down list height allowed. The drop-down list height will be set as the minimum value between the list content height and the maxPickerHeight property.
*/
property int maxPickerHeight: 718
/*!
\qmlproperty string StatusListPicker::enableSelectableItem
This property holds if the item in the list will be highlighted when hovering and clickable in its complete area or just not highlighted and able to be selected by clicking only the checbox or radiobutton area.
*/
property bool enableSelectableItem: true
/*!
\qmlproperty string StatusListPicker::menuAlignment
This property holds the allignment of the menu in terms of the button
*/
property int menuAlignment: StatusListPicker.MenuAlignment.Right
/*!
\qmlproperty enum StatusListPicker::MenuAlignment
This property holds the allignment of the menu in terms of the button
values can be Left, Right or Center
*/
enum MenuAlignment {
Left,
Right,
Center
}
/*
\qmlmethod StatusListPicker::close()
It can be used to force to close the drop-down picker list whenever the consumer needs it. For example by adding an outside MouseArea to close the picker when user clicks outsite the component:
\qml
// Outsite area
MouseArea {
height: root.height
width: root.width
onClicked: { currencyPicker.close() }
}
\endqml
*/
function close() {
picker.visible = false
// Reset searcher:
root.searchText = ""
}
/*!
\qmlsignal StatusListPicker::itemPickerChanged(string key, bool selected)
This signal is emitted when an item changes its selected value.
*/
signal itemPickerChanged(string key, bool selected)
QtObject {
id: d
property var filteredModel: ListModel { }
// Used to set up component and the needed private properties
function initialize() {
if(filteredModel.count === 0) {
// It is necessary to load the model, not loaded yet!
var selected = 0
var selectionText = ""
for(var i = 0; i < root.inputList.count; i++) {
var item = root.inputList.get(i)
d.filteredModel.append(item)
if(item.selected) selected++;
}
// If the given model has more than one selected elements, the behaviour of the list picker will be as a multiple selector with checkboxes although it is
// set in the radiobutton mode. Radiobutton mode is only for mutial-exclusion.
if(selected > 1)
multiSelection = true
// Update selected items text:
d.getSelectedItemsText()
}
}
// Used to update model elements given a specific text by filtering them for its `name` and / or `shortName`.
function applyFilter(text) {
const input = text.toLowerCase()
filteredModel.clear()
for(var i = 0; i < root.inputList.count; i++) {
let item = root.inputList.get(i)
if(item.name.toLowerCase().includes(input) || item.shortName.toLowerCase().includes(input))
filteredModel.append(item)
}
}
function formatSymbolShortNameText(symbol, shortName) {
var formattedText = ""
if(root.printSymbol && symbol)
formattedText = symbol + shortName
else
formattedText = shortName
return formattedText
}
function getSelectedItemsText() {
var res = ""
for(var i = 0; i < root.inputList.count; i++) {
var item = root.inputList.get(i)
if(item.selected) {
if(res != "")
res += ", "
res += d.formatSymbolShortNameText(item.symbol, item.shortName)
}
}
return res
}
// Used to update the base input list model with the new selected property
function updateInputListModel(key, selected, isSingleSelection) {
// If it is a single selection we must ensure that when a new key is selected others are cleared.
// It must be done manually because as there is the option of filterning, the model visualized changes
// and it could be possible to have a filtered list without an element selected (but in the base model
// it is) so, the binding to not selected will not be executed, as in the current filtered model
// there are no changes to update, just only the selected one.
for(var i = 0; i < root.inputList.count; i++) {
if(root.inputList.get(i).key === key) {
root.inputList.get(i).selected = selected
}
else if(isSingleSelection && selected) {
// Clear all the list
root.inputList.get(i).selected = false
}
}
}
}
width: 110
height: 38
Component.onCompleted: d.initialize()
StatusPickerButton {
id: btn
anchors.fill: parent
bgColor: Theme.palette.primaryColor3
contentColor: Theme.palette.primaryColor1
text: picker.selectedItemsText
textPixelSize: 13
type: StatusPickerButton.Type.Down
onClicked: {
picker.visible = !picker.visible
// Restart list position:
content.positionViewAtBeginning()
content.forceActiveFocus()
}
}
Rectangle {
id: picker
property string selectedItemsText: ""
width: content.itemWidth
height: Math.min(content.contentHeight + content.anchors.topMargin + content.anchors.bottomMargin, root.maxPickerHeight)
anchors.left: root.menuAlignment === StatusListPicker.MenuAlignment.Left ? btn.left : undefined
anchors.right: root.menuAlignment === StatusListPicker.MenuAlignment.Right ? btn.right : undefined
anchors.horizontalCenter: root.menuAlignment === StatusListPicker.MenuAlignment.Center ? btn.horizontalCenter : undefined
anchors.top: btn.bottom
anchors.topMargin: 4
visible: false
color: Theme.palette.statusPopupMenu.backgroundColor
radius: 8
layer.enabled: true
layer.effect: DropShadow {
source: picker
horizontalOffset: 0
verticalOffset: 4
radius: 12
samples: 25
spread: 0.2
color: Theme.palette.dropShadow
}
ListView {
id: content
property int itemHeight: 40
property int itemWidth: 360
model: d.filteredModel
width: itemWidth
anchors.top: parent.top
anchors.topMargin: 8
anchors.bottom: parent.bottom
anchors.bottomMargin: 8
currentIndex: -1
clip: true
headerPositioning: ListView.OverlayHeader
header: Rectangle {
id: header
width: content.itemWidth
height: searchInput.height + 24
color: Theme.palette.statusPopupMenu.backgroundColor
z: 3 // Above delegate (z=1) and above section.delegate (z = 2)
StatusBaseInput {
id: searchInput
implicitHeight: 36
width: content.itemWidth - 2 * 18
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
topPadding: 0
bottomPadding: 0
placeholderText: root.placeholderSearchText
text: root.searchText
icon.name: "search"
onTextChanged: {
d.applyFilter(text)
root.searchText = text
}
}
}// End of search input item
delegate: StatusItemPicker {
width: content.itemWidth
height: content.itemHeight
color: mouseArea.containsMouse ? Theme.palette.baseColor4 : "transparent"
image: StatusImageSettings {
source: model.imageSource ? model.imageSource : ""
width: 15
height: 15
isIdenticon: false
}
name: model.name
shortName: model.shortName
selectorType: root.multiSelection ? StatusItemPicker.SelectorType.CheckBox : StatusItemPicker.SelectorType.RadioButton
selected: model.selected
radioGroup: radioBtnGroup
onCheckedChanged: {
d.updateInputListModel(model.key, checked, selectorType === StatusItemPicker.SelectorType.RadioButton)
if(selectorType === StatusItemPicker.SelectorType.RadioButton && checked) {
// Update selected item text
picker.selectedItemsText = d.formatSymbolShortNameText(model.symbol, model.shortName)
}
else {
// Update selected items text (multiple selection, text chain).
picker.selectedItemsText = d.getSelectedItemsText()
}
// Used to notify selected property changes in the specific item picker.
itemPickerChanged(model.key, checked)
}
MouseArea {
id: mouseArea
enabled: root.enableSelectableItem
anchors.fill: parent
cursorShape: root.enableSelectableItem ? Qt.PointingHandCursor : Qt.ArrowCursor
hoverEnabled: true
onClicked: {
if(selectorType === StatusItemPicker.SelectorType.RadioButton) {
// Just only allow to select, not unselect in case of single selection (radiobutton)
if(!selected) selected = !selected
}
else
// In case of multiple selections you can both select and unselect.
selected = !selected
}
}
}
section.property: "category"
section.criteria: ViewSection.FullString
section.delegate: Item {
width: content.itemWidth
height: content.itemHeight
StatusBaseText {
anchors.leftMargin: 18
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
text: section
color: Theme.palette.baseColor1
font.pixelSize: 15
elide: Text.ElideRight
}
}// End of Category item
onActiveFocusChanged: { if(!activeFocus) root.close() }
// Not visual element to control mutual-exclusion of radiobuttons that are not sharing the same parent (inside list view)
ButtonGroup {
id: radioBtnGroup
}
}// End of Content
}// End of Rectangle picker
}
@@ -0,0 +1,127 @@
import QtQuick 2.0
import StatusQ.Core.Theme 0.1
import StatusQ.Core 0.1
/*!
\qmltype StatusMemberListItem
\inherits StatusListItem
\inqmlmodule StatusQ.Components
\since StatusQ.Components 0.1
\brief It is a list item with a specific format to display members of a community or chat. Inherits from \c StatusListItem.
The \c StatusMemberListItem is a clickable / hovering list item with a specific format to display members of a community or chat.
It displays the member avatar, trust and mutual contact indicators, nick name, user name, chat key and information about the member connectivity.
Example of how the control looks like:
\image status_member_list_item.png
Example of how to use it:
\qml
StatusMemberListItem {
nickName: "carmen.eth"
isOnline: false
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
}
StatusMemberListItem {
nickName: "This girl I know from work"
userName: "annabelle"
isOnline: true
}
\endqml
For a list of components available see StatusQ.
*/
StatusListItem {
id: root
/*!
\qmlproperty string StatusMemberListItem::nickName
This property holds the nick name of the member represented.
*/
property string nickName: ""
/*!
\qmlproperty string StatusMemberListItem::userName
This property holds the user name of the member represented.
*/
property string userName: ""
/*!
\qmlproperty string StatusMemberListItem::chatKey
This property holds the chat key of the member represented.
*/
property string chatKey: ""
/*!
\qmlproperty string StatusMemberListItem::isMutualContact
This property holds if the member represented is a mutual contact.
*/
property bool isMutualContact: false
/*!
\qmlproperty string StatusMemberListItem::trustIndicator
This property holds the trust indicator of the member represented. Possible values are:
\list
\li StatusContactVerificationIcons.TrustedType.None
\li StatusContactVerificationIcons.TrustedType.Verified
\li StatusContactVerificationIcons.TrustedType.Untrustworthy
\endlist
*/
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
/*!
\qmlproperty string StatusMemberListItem::isOnline
This property holds the connectivity status of the member represented.
*/
property bool isOnline: false
QtObject {
id: d
// Subtitle composition:
function composeSubtitile() {
var compose = ""
if(root.userName !== "" && root.nickName !== "")
compose = "(" + root.userName + ")"
if(compose !== "" && root.chatKey !== "")
// Composition
compose += " • " + composeShortKeyChat(root.chatKey)
else if(root.chatKey !== "")
compose = composeShortKeyChat(root.chatKey)
return compose
}
// Short keychat composition:
function composeShortKeyChat(chatKey) {
return chatKey.substring(0, 5) + "..." + chatKey.substring(chatKey.length - 3)
}
}
// root object settings:
title: (root.nickName === "") ? root.userName : root.nickName
statusListItemTitleIcons.sourceComponent: StatusContactVerificationIcons {
isMutualContact: root.isMutualContact
trustIndicator: root.trustIndicator
}
subTitle: d.composeSubtitile()
statusListItemSubTitle.font.pixelSize: 10
icon.isLetterIdenticon: !root.image.source.toString()
statusListItemIcon.badge.visible: true
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
implicitWidth: 256
implicitHeight: Math.max(56, statusListItemTitleArea.height + leftPadding)
leftPadding: 8
image.width: 32
image.height: 32
icon.width: 32
icon.height: 32
statusListItemIcon.anchors.verticalCenter: sensor.verticalCenter
statusListItemIcon.anchors.top: undefined
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
}
+200
View File
@@ -0,0 +1,200 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import "./private/statusMessage"
Rectangle {
id: statusMessage
enum ContentType {
Unknown = 0,
Text = 1,
Emoji = 2,
Image = 3,
Sticker = 4,
Audio = 5,
Transaction = 6,
Invitation = 7
}
property alias messageHeader: messageHeader
property alias quickActions:quickActionsPanel.quickActions
property alias statusChatInput: editComponent.inputComponent
property alias linksComponent: linksLoader.sourceComponent
property alias footerComponent: footer.sourceComponent
property alias timestamp: messageHeader.timestamp
property string resendText: ""
property string cancelButtonText: ""
property string saveButtonText: ""
property string loadingImageText: ""
property string errorLoadingImageText: ""
property string audioMessageInfoText: ""
property string pinnedMsgInfoText: ""
property bool isAppWindowActive: false
property bool editMode: false
property bool isAReply: false
property StatusMessageDetails messageDetails: StatusMessageDetails {}
property StatusMessageDetails replyDetails: StatusMessageDetails {}
signal profilePictureClicked()
signal senderNameClicked()
signal editCompleted(var newMsgText)
signal replyProfileClicked()
signal stickerLoaded()
signal imageClicked(var imageSource)
signal resendClicked()
height: childrenRect.height
color: hoverHandler.hovered ? (messageDetails.hasMention ? Theme.palette.mentionColor3 : messageDetails.isPinned ? Theme.palette.pinColor2 : Theme.palette.baseColor2) : messageDetails.hasMention ? Theme.palette.mentionColor4 : messageDetails.isPinned ? Theme.palette.pinColor3 : "transparent"
HoverHandler {
id: hoverHandler
}
ColumnLayout {
id: messageLayout
width: parent.width
StatusMessageReply {
Layout.fillWidth: true
visible: isAReply
replyDetails: statusMessage.replyDetails
onReplyProfileClicked: statusMessage.replyProfileClicked()
audioMessageInfoText: statusMessage.audioMessageInfoText
}
RowLayout {
spacing: 8
Layout.fillWidth: true
StatusSmartIdenticon {
id: profileImage
Layout.alignment: Qt.AlignTop
Layout.topMargin: 10
Layout.leftMargin: 16
image: messageDetails.profileImage
name: messageHeader.displayName
MouseArea {
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
onClicked: statusMessage.profilePictureClicked()
}
}
Column {
spacing: 4
Layout.alignment: Qt.AlignTop
Layout.topMargin: 10
Layout.fillWidth: true
StatusPinMessageDetails {
visible: messageDetails.isPinned && !editMode
pinnedMsgInfoText: statusMessage.pinnedMsgInfoText
pinnedBy: messageDetails.pinnedBy
}
StatusMessageHeader {
id: messageHeader
width: parent.width
displayName: messageDetails.displayName
secondaryName: messageDetails.secondaryName
tertiaryDetail: messageDetails.chatID
isMutualContact: messageDetails.isMutualContact
trustIndicator: messageDetails.trustIndicator
resendText: statusMessage.resendText
showResendButton: messageDetails.hasExpired && messageDetails.amISender
onClicked: statusMessage.senderNameClicked()
onResendClicked: statusMessage.resendClicked()
visible: !editMode
}
Loader {
active: !editMode && !!messageDetails.messageText
width: parent.width
visible: active
sourceComponent: StatusTextMessage {
width: parent.width
textField.text: messageDetails.messageText
}
}
Loader {
active: messageDetails.contentType === StatusMessage.ContentType.Image && !editMode
visible: active
sourceComponent: StatusImageMessage {
source: messageDetails.contentType === StatusMessage.ContentType.Image ? messageDetails.messageContent : ""
onClicked: statusMessage.imageClicked()
shapeType: messageDetails.amISender ? StatusImageMessage.ShapeType.RIGHT_ROUNDED : StatusImageMessage.ShapeType.LEFT_ROUNDED
}
}
StatusSticker {
visible: messageDetails.contentType === StatusMessage.ContentType.Sticker && !editMode
image.source: messageDetails.messageContent
onLoaded: statusMessage.stickerLoaded()
}
Loader {
active: messageDetails.contentType === StatusMessage.ContentType.Audio && !editMode
visible: active
sourceComponent: StatusAudioMessage {
audioSource: messageDetails.messageContent
hovered: hoverHandler.hovered
audioMessageInfoText: statusMessage.audioMessageInfoText
}
}
Loader {
id: linksLoader
active: !!linksLoader.sourceComponent
visible: active
}
Loader {
id: transactionBubbleLoader
active: messageDetails.contentType === StatusMessage.ContentType.Transaction && !editMode
visible: active
}
Loader {
id: invitationBubbleLoader
active: messageDetails.contentType === StatusMessage.ContentType.Invitation && !editMode
visible: active
}
StatusEditMessage {
id: editComponent
width: parent.width
msgText: messageDetails.messageText
visible: editMode
saveButtonText: statusMessage.saveButtonText
cancelButtonText: statusMessage.cancelButtonText
onCancelEditClicked: editMode = false
onEditCompleted: {
editMode = false
statusMessage.editCompleted(newMsgText)
}
}
StatusBaseText {
id: retryLbl
color: Theme.palette.dangerColor1
text: statusMessage.resendText
font.pixelSize: 12
visible: messageDetails.hasExpired && messageDetails.amISender && !messageDetails.timestamp && !editMode
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: statusMessage.resendClicked()
}
}
Loader {
id: footer
active: sourceComponent && !editMode
visible: active
}
}
}
}
StatusMessageQuickActions {
id: quickActionsPanel
anchors.right: parent.right
anchors.rightMargin: 20
anchors.top: parent.top
anchors.topMargin: -8
visible: hoverHandler.hovered && !editMode
}
}

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