Compare commits

..
Author SHA1 Message Date
Eric Mastro 612cf4d3d5 feat: async validators
Allows asynchronous validation, with the ability to track the validated value for use in the StatusInput as a value that is separate from the entered text.

Async operations are debounced internally to the StatusAsyncValidator.

#### Introduce StatusAsyncValidator component:
- `validate`: the input value to this function is the value sent to `asyncComplete`, which must be called by the validator. Return true when the value from the async operation is valid.
- `asyncComplete`: signal to be called by the validator after the async operation has completed. It should contain the value returned by the async operation that should be validated in `validate`.
- `validatedValue`: This is the valid value returned from the async operation. It it tracked separately so that the input text on the `StatusInput` can remain as entered by the user. Use this property and the `onValidatedValueChanged` signal handler for the “real” value to be used by other components.
2021-09-17 13:45:22 +02:00
Pascal Precht e634c7ba20 feat(StatusInput): add support for asynchronous validators
This adds support for asynchronous validators which are also just `StatusValidator`.

There are a few differences to syncronous validators though:

1. `validate` function doesn't return, it's only used to trigger the async
   validation. Ideally it would return an async object like Promise or Observable
   but since we have to rely on QML `Connections`, this won't work.
2. As mentioned, `Connections` are needed to listen to async events so the
  validation can be resolved.
3. Validation has to be resolved by calling `input.updateValidity` inside the validator.
   That API notifies `StatusInput` that validation is has been performed and expects
   the name of the validator as well as either a boolean (true), if validation was successful,
   or, if validation has failed, a boolean (false) or an error object.

Here's a `StatusENSValidator` as an example:

```qml
StatusValidator {

    id: root

    name: "ensValidator"
    errorMessage: "Couldn't resolve ENS name."

    readonly property string uuid: Utils.uuid()

    property int debounceTime: 600

    signal ensResolved(string address)

    validate: Backpressure.debounce(root, root.debounceTime, function (name) {
        name = name.startsWith("@") ? name.substring(1) : name
        walletModel.ensView.resolveENS(name, uuid)
    })

    Connections {
        target: walletModel.ensView
        onEnsWasResolved: {
            if (uuid !== root.uuid) {
                return
            }
            root.ensResolved(resolvedAddress)
            input.updateValidityAndPendingState(root.name, resolvedAddress !== "")
        }
    }
}
```

Closes #395
2021-09-17 13:45:20 +02:00
138 changed files with 2393 additions and 8507 deletions
-1
View File
@@ -12,4 +12,3 @@ Makefile
.qmake.stash
*_qml.cpp
*_qmlcache.qrc
sandbox/qmlcache_loader.cpp
-255
View File
@@ -1,258 +1,3 @@
<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)
#### Bug Fixes
* **StatusModal:** render footer correctly based on `showFooter` flag ([da9dc2f4](da9dc2f4))
* **StatusRoundButton:** ensure disabled state uses correct background color ([eb4aae40](eb4aae40))
#### Features
* **StatusQ.Controls:**
* introduce `StatusWalletColorSelect` control ([ea9a5602](ea9a5602), closes [#467](467))
* introduce `StatusWalletColorButton` component ([597ae192](597ae192), closes [#466](466))
* **StatusQ.Platform:** introduce StatusMacNotification component ([d301b94c](d301b94c))
<a name=""></a>
## Version 0.15.0 (2021-10-26)
#### Features
* **StatusQ.Controls:**
* introduce StatusChatCommandButton ([4cc0d2bb](4cc0d2bb), closes [#429](429))
* introduce `StatusTabBarIconButton` component ([4bcd89b3](4bcd89b3), closes [#428](428))
<a name=""></a>
## Version 0.14.0 (2021-10-25)
#### Bug Fixes
* **Spellchecking:** Add check for hunspell existence ([ab9ab249](ab9ab249))
* **StatusModal:**
* ensure `onEditButtonClicked` signal is emitted ([074dc22b](074dc22b), closes [#454](454))
* expose `header.editable` property ([9c5f79a6](9c5f79a6), closes [#452](452))
#### Features
* **StatusSmartIdenticon:** Created a new StatusQ componnent to accomodate: ([14527483](14527483))
<a name=""></a>
## Version 0.13.0 (2021-10-19)
#### Bug Fixes
* use proper double checkmark icon ([8aba017c](8aba017c))
* **StatusBaseButton:** introduce missing `highlighted` property ([a3748920](a3748920))
#### Features
* **StatusFlatRoundButton:** Update the StatusFlatRoundButton to take over button behaviour from StatusIconButton under ui/shared/status ([71fbdef1](71fbdef1))
<a name=""></a>
## Version 0.12.0 (2021-10-18)
#### Features
* Resolve StatusQ modules highlighting and add qml compiler for detecting coompile time errors ([e1b0f2dc](e1b0f2dc))
* **StatusModal:** Add edit avatar button ([5043b0b6](5043b0b6))
* **StatusQ.Components:** introduce `StatusAddress` component ([6789446d](6789446d), closes [#430](430))
* **StatusQ.Controls:**
* introduce StatusColorSelector component ([bdd69955](bdd69955), closes [#444](444))
* introduce `StatusAssetSelector` component ([9fdc9aea](9fdc9aea), closes [#442](442))
* introduce `StatusAccountSelector` component ([5e15cc49](5e15cc49), closes [#435](435))
* introduce `StatusSelect` ([6e10959e](6e10959e), closes [#436](436))
* **StatusQ.Popups:** introduce `StatusMenuItemDelegate` ([0764e25a](0764e25a))
#### Breaking Changes
* **StatusQ.Popups:** introduce `StatusMenuItemDelegate` ([0764e25a](0764e25a))
<a name=""></a>
## Version 0.11.1(2021-10-12)
#### Bug Fixes
* Sandbox doesn't build on Linux machines ([dce45c2f](dce45c2f))
* **StatusChatInfoButton:** StatusChatInfoButton takes up entire available width ([c276a90e](c276a90e))
<a name=""></a>
## v0.11.0 (2021-09-27)
#### Bug Fixes
* track category opened state ([0631d500](0631d500))
* **StatusChatList:** ensure right click popup opens in correct position ([a2e3659d](a2e3659d))
* **StatusSearchPopup:** use correct theme color for search result text ([654bd9f2](654bd9f2))
* **StatusSpellcheckingMenuItems:** Exact menu items order ([478177f2](478177f2))
#### Features
* add star icons (#422) ([5c3267f7](5c3267f7))
<a name=""></a>
## v0.10.0 (2021-09-20)
#### Bug Fixes
* **StatusChatInfoToolBar:** Right anchored title in StatusChatInfoToolBar ([6e8a36be](6e8a36be))
* **StatusChatListCategoryItem:** Disable sensor when chevron clicked ([c83641d2](c83641d2))
* **StatusQ.Controls.Validators:** fix bug that addressOrEns validator isn't properly exposed in QML ([1374c193](1374c193))
#### Features
* **Spellchecker:** Add Spellchecker class ([c65f80d2](c65f80d2))
* **Spellchecking:**
* Add dictionaries ([1d12d222](1d12d222))
* Add huspell dependency ([f9457ef3](f9457ef3))
* **StatusChatList:** expose `statusChatListItems` Repeater ([40c0e48b](40c0e48b))
* **StatusExpandableItem:** Correct placement of expandable region in tertiary type ([1f244f62](1f244f62))
* **StatusInput:**
* add support for asynchronous validators ([8820cd89](8820cd89), closes [#395](395))
* introduce `leftPadding` and `rightPadding` properties ([13dc8ae3](13dc8ae3))
* introduce `reset` API ([a2ad08e4](a2ad08e4))
* **StatusSpellcheckingMenuItems:** Add spellchecking menu ([3e24b710](3e24b710))
<a name=""></a>
## v0.9.0 (2021-09-13)
@@ -240,63 +240,6 @@ Column {
loading: true
size: StatusBaseButton.Size.Small
}
// Tertiary
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Tertiary
icon.name: "gif"
}
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Tertiary
icon.name: "gif"
enabled: false
}
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Tertiary
icon.name: "gif"
loading: true
}
// No background Tertiary
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Tertiary
color: "transparent"
icon.name: "gif"
}
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Tertiary
icon.name: "gif"
color: "transparent"
enabled: false
}
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Tertiary
icon.name: "gif"
color: "transparent"
loading: true
}
// Quartenery
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Quaternary
icon.name: "gif"
}
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Quaternary
icon.name: "gif"
enabled: false
}
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Quaternary
icon.name: "gif"
loading: true
}
}
StatusPickerButton {
@@ -12,21 +12,6 @@ GridLayout {
columnSpacing: 5
rowSpacing: 5
StatusSelectableText {
color: Theme.palette.baseColor1
text: "This is a multiline paragraph that can be selected and copied. A paragraph is a group of words put together to form a group that is usually longer than a sentence. Paragraphs are often made up of several sentences. There are usually between three and eight sentences. Paragraphs can begin with an indentation (about five spaces), or by missing a line out, and then starting again."
font.pixelSize: 15
width: 300
multiline: true
}
StatusSelectableText {
color: Theme.palette.baseColor1
text: "<p>This is a selectable link in rich text format to test <a href='www.google.com'>www.google.com</a></p>"
font.pixelSize: 15
width: 200
}
StatusIconTabButton {
icon.name: "chat"
}
@@ -188,19 +173,4 @@ 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
}
}
+765 -99
View File
@@ -9,9 +9,6 @@ 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
@@ -21,31 +18,6 @@ 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
@@ -76,74 +48,32 @@ Rectangle {
id: navBar
communityTypeRole: "sectionType"
communityTypeValue: appSectionType.community
sectionModel: Models.demoAppSectionsModel
property bool communityAdded: false
onAboutToUpdateFilteredRegularModel: {
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
navBarChatButton: StatusNavBarTabButton {
icon.name: "chat"
tooltip.text: "Chat"
checked: appView.sourceComponent == statusAppChatView
onClicked: {
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)
}
appView.sourceComponent = statusAppChatView
}
}
communityNavBarButton: StatusNavBarTabButton {
navBarCommunityTabButtons.model: ListModel {
ListElement {
name: "Status Community"
tooltipText: "Status Community"
}
}
navBarCommunityTabButtons.delegate: StatusNavBarTabButton {
id: communityBtn
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
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
onClicked: {
if(model.sectionType === appSectionType.community)
{
appView.sourceComponent = statusAppCommunityView
demoApp.setActiveItem(model.sectionId)
}
appView.sourceComponent = statusAppCommunityView
}
popupMenu: StatusPopupMenu {
@@ -174,7 +104,39 @@ 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 {
@@ -186,31 +148,735 @@ Rectangle {
Component {
id: statusAppChatView
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
}
}
}
}
}
}
Component {
id: statusAppCommunityView
StatusAppCommunityView {
communityDetailModalTitle: demoCommunityDetailModal.header.title
communityDetailModalImage: demoCommunityDetailModal.header.image.source
onChatInfoButtonClicked: {
demoCommunityDetailModal.open();
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
}
}
}
}
}
}
Component {
id: statusAppProfileSettingsView
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
}
}
}
DemoContactRequestsModal {
StatusModal {
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()
}
]
}
DemoCommunityDetailModal {
StatusModal {
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
@@ -0,0 +1,295 @@
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"
}
]
}
}
}
@@ -85,8 +85,7 @@ GridLayout {
StatusChatListItem {
name: "has-mentions"
type: StatusChatListItem.Type.PublicChat
hasUnreadMessages: true
notificationsCount: 1
badge.value: 1
}
StatusChatListItem {
@@ -101,7 +100,7 @@ GridLayout {
type: StatusChatListItem.Type.PublicChat
muted: true
hasUnreadMessages: true
notificationsCount: 1
badge.value: 1
}
StatusChatListItem {
@@ -131,7 +130,7 @@ GridLayout {
selected: true
muted: true
hasUnreadMessages: true
notificationsCount: 1
badge.value: 1
}
@@ -287,7 +286,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
StatusListItem {
title: "Title"
icon.isLetterIdenticon: true
icon.color: "orange"
icon.background.color: "orange"
}
StatusListItem {
@@ -346,38 +345,4 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
title: "Contact requests"
requestsCount: 3
}
StatusMemberListItem {
nickName: "This is an example"
userName: "annabelle"
chatKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
trustIndicator: StatusMemberListItem.TrustedType.Verified
isMutualContact: true
image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
image.isIdenticon: true
isOnline: true
}
StatusMemberListItem {
nickName: "carmen.eth"
isOnline: false
trustIndicator: StatusMemberListItem.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
}
}
+336
View File
@@ -0,0 +1,336 @@
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
}]}
}
}
@@ -53,11 +53,6 @@ Column {
onClicked: modalWithIdenticon.open()
}
StatusButton {
text: "Modal with editable identicon"
onClicked: modalWithEditableIdenticon.open()
}
StatusButton {
text: "Modal with long titles"
onClicked: modalWithLongTitles.open()
@@ -68,16 +63,6 @@ Column {
onClicked: modalWithHeaderPopupMenu.open()
}
StatusButton {
text: "Spellchecking menu"
onClicked: spellMenu.open()
}
StatusButton {
text: "Modal with Editable Title"
onClicked: editTitleModal.open()
}
StatusModal {
id: simpleModal
anchors.centerIn: parent
@@ -269,33 +254,6 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
]
}
StatusModal {
id: modalWithEditableIdenticon
anchors.centerIn: parent
header.title: "Header"
header.subTitle: "SubTitle"
header.headerImageEditable: true
header.image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
header.image.isIdenticon: true
contentItem: StatusBaseText {
anchors.centerIn: parent
text: "Some text content"
font.pixelSize: 15
color: Theme.palette.directColor1
}
rightButtons: [
StatusButton {
text: "Change text"
onClicked: {
modalWithIdenticon.contentItem.text = "Changed!"
}
}
]
}
StatusModal {
id: modalWithLongTitles
anchors.centerIn: parent
@@ -346,22 +304,9 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
}
}
StatusModal {
id: editTitleModal
anchors.centerIn: parent
header.title: "This title can be edited"
header.editable: true
}
ListModel {
id: dummyAccountsModel
ListElement{name: "Account 1"; iconName: "filled-account"}
ListElement{name: "Account 2"; iconName: "filled-account"}
}
StatusSpellcheckingMenuItems {
id: spellMenu
anchors.centerIn: parent
suggestions: ["suggestion1", "suggestion2", "suggestion3", "suggestion4"]
}
}
-443
View File
@@ -1,443 +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
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
}
}
}
}
}
}
-103
View File
@@ -1,103 +0,0 @@
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
contactType: model.contactType
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"
}
]
}
}
-236
View File
@@ -1,236 +0,0 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQml.Models 2.2
import QtGraphicalEffects 1.0
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
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
implicitHeight: 44
toLabelText: qsTr("To: ")
warningText: qsTr("5 USER LIMIT REACHED")
//simulate model filtering, TODO this
//makes more sense to be provided by the backend
//figure how real implementation should look like
property ListModel sortedList: ListModel { }
onTextChanged: {
sortedList.clear();
if (text !== "") {
for (var i = 0; i < contactsModel.count; i++ ) {
var entry = contactsModel.get(i);
if (entry.name.toLowerCase().includes(text.toLowerCase())) {
sortedList.insert(sortedList.count, {"publicId": entry.publicId, "name": entry.name,
"icon": entry.icon, "isIdenticon": entry.isIdenticon,
"onlineStatus": entry.onlineStatus});
userListView.model = sortedList;
}
}
} else {
userListView.model = contactsModel;
}
}
}
StatusButton {
implicitHeight: 44
enabled: (tagSelector.namesModel.count > 0)
text: "Confirm"
}
}
contentItem: Item {
anchors.fill: parent
anchors.topMargin: headerRow.height + 16
Item {
anchors.fill: parent
visible: (contactsModel.count > 0)
StatusBaseText {
id: contactsLabel
font.pixelSize: 15
anchors.left: parent.left
anchors.leftMargin: 8
color: Theme.palette.baseColor1
text: qsTr("Contacts")
}
Control {
width: 360
anchors {
top: contactsLabel.bottom
topMargin: 8//Style.current.padding
bottom: !statusPopupMenuBackgroundContent.visible ? parent.bottom : undefined
bottomMargin: 20//Style.current.bigPadding
}
height: 16 + (!statusPopupMenuBackgroundContent.visible ? parent.height :
(((userListView.count * 64) > parent.height) ? parent.height : (userListView.count * 64)))
x: (statusPopupMenuBackgroundContent.visible && (tagSelector.namesModel.count > 0) &&
((tagSelector.textEdit.x + 24 + statusPopupMenuBackgroundContent.width) < parent.width))
? (tagSelector.textEdit.x + 24) : 0
background: Rectangle {
id: statusPopupMenuBackgroundContent
anchors.fill: parent
visible: (tagSelector.sortedList.count > 0)
color: Theme.palette.statusPopupMenu.backgroundColor
radius: 8
layer.enabled: true
layer.effect: DropShadow {
width: statusPopupMenuBackgroundContent.width
height: statusPopupMenuBackgroundContent.height
x: statusPopupMenuBackgroundContent.x
visible: statusPopupMenuBackgroundContent.visible
source: statusPopupMenuBackgroundContent
horizontalOffset: 0
verticalOffset: 4
radius: 12
samples: 25
spread: 0.2
color: Theme.palette.dropShadow
}
}
contentItem: ListView {
id: userListView
anchors.fill: parent
anchors.topMargin: 8
anchors.bottomMargin: 8
clip: true
model: contactsModel
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded
}
boundsBehavior: Flickable.StopAtBounds
delegate: Item {
id: wrapper
anchors.right: parent.right
anchors.left: parent.left
height: 64
property bool hovered: false
Rectangle {
id: rectangle
anchors.fill: parent
anchors.rightMargin: 8
anchors.leftMargin: 8
radius: 8
visible: (tagSelector.sortedList.count > 0)
color: (wrapper.hovered) ? Theme.palette.baseColor2 : "transparent"
}
StatusSmartIdenticon {
id: contactImage
anchors.left: parent.left
anchors.leftMargin: 16//Style.current.padding
anchors.verticalCenter: parent.verticalCenter
name: model.name
icon: StatusIconSettings {
width: 28
height: 28
letterSize: 15
}
image: StatusImageSettings {
width: 28
height: 28
source: model.icon
isIdenticon: model.isIdenticon
}
}
StatusBaseText {
id: contactInfo
text: model.name
anchors.right: parent.right
anchors.rightMargin: 8
anchors.left: contactImage.right
anchors.leftMargin: 16
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
color: Theme.palette.directColor1
font.weight: Font.Medium
font.pixelSize: 15
}
StatusBadge {
id: statusBadge
width: 15
height: 15
anchors.left: contactImage.right
anchors.leftMargin: -8
anchors.bottom: contactImage.bottom
border.width: 3
border.color: Theme.palette.statusAppNavBar.backgroundColor
color: {
if (model.onlineStatus === 1)
return Theme.palette.successColor1;
else if (model.onlineStatus === 2)
return Theme.palette.pinColor1;
else if (model.onlineStatus === 3)
return Theme.palette.dangerColor1;
return "transparent"
}
}
MouseArea {
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
hoverEnabled: true
onEntered: {
wrapper.hovered = true;
}
onExited: {
wrapper.hovered = false;
}
onClicked: {
tagSelector.insertTag(model.name, model.publicId);
}
}
}
}
}
Component.onCompleted: {
if (visible) {
tagSelector.textEdit.forceActiveFocus();
}
}
}
StatusBaseText {
visible: (contactsModel.count === 0)
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;
}
}
}
}
}
@@ -1,111 +0,0 @@
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
}
}
}
@@ -1,40 +0,0 @@
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()
}
]
}
-194
View File
@@ -1,194 +0,0 @@
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: parent.width
height: searchInput.height
anchors.top: headline.bottom
anchors.topMargin: 16
anchors.right: parent.right
anchors.rightMargin: 8
StatusBaseInput {
id: searchInput
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: 17
implicitHeight: 36
topPadding: 8
bottomPadding: 0
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
width: parent.width
spacing: 8
StatusContactRequestsIndicatorListItem {
anchors.horizontalCenter: parent.horizontalCenter
title: "Contact requests"
requestsCount: 3
sensor.onClicked: demoContactRequestsModal.open()
}
StatusChatList {
anchors.horizontalCenter: parent.horizontalCenter
model: Models.demoChatListItems
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.dummyContactsModel
}
}
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
}
}
}
}
}
-272
View File
@@ -1,272 +0,0 @@
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.userName
chatKey: model.chatKey
trustIndicator: model.trustIndicator
isMutualContact: model.isMutualContact
image.source: model.source
image.isIdenticon: model.isIdenticon
isOnline: model.isOnline
}
}
}
}
@@ -1,77 +0,0 @@
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
-1
View File
@@ -1 +0,0 @@
singleton Models 1.0 Models.qml
Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

-19
View File
@@ -1,19 +0,0 @@
/*!
\page statusq-index.html
\title StatusQ
\brief A components library for Status desktop client.
StatusQ provides a collection of components....
StatusQ - Components and Interfaces
\list
\li \l{StatusQ Components}{Components}
\li \l{StatusQ Controls}{Controls}
\li \l{StatusQ Core}{Core}
\li \l{StatusQ Layout}{Layout}
\li \l{StatusQ Platform}{Platform}
\li \l{StatusQ Popups}{Popups}
\endlist
*/
-41
View File
@@ -1,41 +0,0 @@
/*!
\qmlmodule StatusQ.Components 0.1
\title StatusQ Components
\brief Basic set of Components StatusQ components
This is a listing of all Components components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusAddress}
\li \l{StatusBadge}
\li \l{StatusChatInfoToolBar}
\li \l{StatusChatList}
\li \l{StatusChatListItem}
\li \l{StatusImageSettings}
\li \l{StatusChatListCategory}
\li \l{StatusChatListCategoryItem}
\li \l{StatusChatListAndCategories}
\li \l{StatusChatToolBar}
\li \l{StatusContactRequestsIndicatorListItem}
\li \l{StatusDescriptionListItem}
\li \l{StatusLetterIdenticon}
\li \l{StatusListItem}
\li \l{StatusListSectionHeadline}
\li \l{StatusLoadingIndicator}
\li \l{StatusMemberListItem}
\li \l{StatusNavigationListItem}
\li \l{StatusNavigationPanelHeadline}
\li \l{StatusRoundIcon}
\li \l{StatusRoundedImage}
\li \l{StatusMacWindowButtons}
\li \l{StatusListItemBadge}
\li \l{StatusExpandableItem}
\li \l{StatusSmartIdenticon}
\li \l{StatusMessage}
\li \l{StatusMessageDetails}
\li \l{StatusTagSelector}
\li \l{StatusToastMessage}
\endlist
*/
-43
View File
@@ -1,43 +0,0 @@
/*!
\qmlmodule StatusQ.Controls 0.1
\title StatusQ Controls
\brief Basic set of Controls StatusQ components
This is a listing of all Controls components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusAccountSelector}
\li \l{StatusAssetSelector}
\li \l{StatusBanner}
\li \l{StatusChatCommandButton}
\li \l{StatusChatInfoButton}
\li \l{StatusChatListCategoryItemButton}
\li \l{StatusColorSelector}
\li \l{StatusIconTabButton}
\li \l{StatusNavBarTabButton}
\li \l{StatusTabBarIconButton}
\li \l{StatusToolTip}
\li \l{StatusBaseButton}
\li \l{StatusButton}
\li \l{StatusFlatButton}
\li \l{StatusRoundButton}
\li \l{StatusFlatRoundButton}
\li \l{StatusSwitch}
\li \l{StatusRadioButton}
\li \l{StatusCheckBox}
\li \l{StatusSlider}
\li \l{StatusSelect}
\li \l{StatusBaseInput}
\li \l{StatusInput}
\li \l{StatusPickerButton}
\li \l{StatusProgressBar}
\li \l{StatusPasswordStrengthIndicator}
\li \l{StatusSwitchTabButton}
\li \l{StatusSwitchTabBar}
\li \l{StatusSelectableText}
\li \l{StatusWalletColorButton}
\li \l{StatusWalletColorSelect}
\endlist
*/
-22
View File
@@ -1,22 +0,0 @@
/*!
\qmlmodule StatusQ.Core 0.1
\title StatusQ Core
\brief Basic set of Core StatusQ components
This is a listing of all Core components. These
files are available for general import and they are based off the \l{https://doc.qt.io/qt-5/qtquick-qmlmodule.html}{Qt
Quick Primitives} and \l{https://doc.qt.io/archives/qt-5.11/qtquick-controls2-qmlmodule.html}{Qt Quick Controls 2}.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusAppNavBarFilterModel}
\li \l{StatusBaseText}
\li \l{StatusIcon}
\li \l{StatusIconBackgroundSettings}
\li \l{StatusIconSettings}
\li \l{StatusImageSettings}
\li \l{StatusModalHeaderSettings}
\li \l{StatusTooltipSettings}
\endlist
*/
-16
View File
@@ -1,16 +0,0 @@
/*!
\qmlmodule StatusQ.Layout 0.1
\title StatusQ Layout
\brief Basic set of Layout StatusQ components
This is a listing of all Layout components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusAppLayout}
\li \l{StatusAppNavBar}
\li \l{StatusAppTwoPanelLayout}
\li \l{StatusAppThreePanelLayout}
\endlist
*/
-15
View File
@@ -1,15 +0,0 @@
/*!
\qmlmodule StatusQ.Platform 0.1
\title StatusQ Platform
\brief Basic set of Platform StatusQ components
This is a listing of all Platform components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusMacTrafficLights}
\li \l{StatusMacNotification}
\li \l{StatusWindowsTitleBar}
\endlist
*/
-22
View File
@@ -1,22 +0,0 @@
/*!
\qmlmodule StatusQ.Popups 0.1
\title StatusQ Popups
\brief Basic set of Popups StatusQ components
This is a listing of all Popups components.
This module is part of the \l{StatusQ}{StatusQ} project.
\list
\li \l{StatusMenuSeparator}
\li \l{StatusPopupMenu}
\li \l{StatusMenuItem}
\li \l{StatusMenuItemDelegate}
\li \l{StatusModal}
\li \l{StatusSearchPopup}
\li \l{StatusModalDivider}
\li \l{StatusSearchPopupMenuItem}
\li \l{StatusSearchLocationMenu}
\li \l{StatusSpellcheckingMenuItems}
\endlist
*/
-36
View File
@@ -1,36 +0,0 @@
project = StatusQ
version = 0.1
description = StatusQ Project
url = https://github.com/status-im/StatusQ
#These are set implictly by qdoc as well, but only with these the module header can be found
includepaths = -I . \
-I $PWD/../../src/StatusQ
imagedirs = src/images
sourcedirs += src \
$PWD/../../src/StatusQ/Components \
$PWD/../../src/StatusQ/Controls \
$PWD/../../src/StatusQ/Core \
$PWD/../../src/StatusQ/Layout \
$PWD/../../src/StatusQ/Platform \
$PWD/../../src/StatusQ/Popups \
sources.fileextensions = "*.cpp *.qdoc *.qml"
depends += qtcore \
qtquick \
qtqml \
qtgui \
qtdoc \
qtquickcontrols2
navigation.homepage = "StatusQ"
outputdir = $PWD/html
outputformats = HTML
HTML.stylesheets = style.css
HTML.headerstyles = "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\"/>\n"
HTML.postheader = "<p class=\"header\"><small>StatusQ - A Components selection for Status dekstop client. </p></small></p><hr/>"
HTML.footer = "<hr/><div class=\"footer\"><p><acronym title=\"Copyright\">&copy;</acronym> 2022 Status. All rights reserved. <a href=\"https://status.im\" target=\"_blank\"><small>status.im</a></small></p></div>"
-41
View File
@@ -1,41 +0,0 @@
body {
font-family: "Verdana";
font-size: 14px;
max-width: 80%;
margin: auto;
}
h1, h2, h3 {
color: #4360DF;
}
div.sidebar {
float: right;
}
pre {
padding: 15px;
}
div.qmlproto {
padding-left: 15px;
padding-right: 15px;
}
pre, div.qmlproto {
font-family: "Courier New";
font-size: 20px;
margin-left: 2em;
background-color: #F0F2F5;
}
hr {
margin-top: 2em;
margin-bottom: 2em;
}
p.header {
margin-bottom: -1em;
}
p.footer {
text-align: right;
margin-top: -1em;
}
+123 -168
View File
@@ -12,8 +12,6 @@ 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
@@ -33,33 +31,11 @@ StatusWindow {
Component.onCompleted: {
Theme.palette = lightTheme
apiDocsButton.checked = true
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 {
id: appLayout
anchors.fill: parent
@@ -67,36 +43,37 @@ StatusWindow {
appNavBar: StatusAppNavBar {
height: rootWindow.height
communityTypeRole: "sectionType"
communityTypeValue: appSectionType.community
sectionModel: Models.mainAppSectionsModel
navBarChatButton: StatusNavBarTabButton {
icon.name: "refresh"
tooltip.text: "Reload App"
onClicked: app.restartQml()
}
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)
{
navBarTabButtons: [
StatusNavBarTabButton {
id: apiDocsButton
icon.name: "edit"
tooltip.text: "API Documentation"
onClicked: {
stackView.clear()
stackView.push(libraryDocumentationCmp)
rootWindow.setActiveItem(sectionId)
checked = !checked
demoAppButton.checked = false
}
else if(model.sectionType === appSectionType.demoApp)
{
},
StatusNavBarTabButton {
id: demoAppButton
icon.name: "status"
tooltip.text: "Demo Application"
checked: stackView.currentItem == demoAppCmp
onClicked: {
stackView.clear()
stackView.push(demoAppCmp)
rootWindow.setActiveItem(model.sectionId)
checked = !checked
apiDocsButton.checked = false
}
}
}
]
}
appView: StackView {
@@ -124,14 +101,6 @@ StatusWindow {
id: libraryDocumentationCmp
StatusAppTwoPanelLayout {
id: mainPageView
function page(name) {
viewLoader.source = Qt.resolvedUrl("./pages/" + name + "Page.qml");
}
function control(name) {
viewLoader.source = Qt.resolvedUrl("./controls/" + name + ".qml");
}
leftPanel: Item {
anchors.fill: parent
@@ -151,142 +120,71 @@ StatusWindow {
StatusListSectionHeadline { text: "StatusQ.Core" }
StatusNavigationListItem {
title: "Icons"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.control(title);
title: "Icons"
selected: page.sourceComponent == iconsComponent
onClicked: page.sourceComponent = iconsComponent
}
StatusListSectionHeadline { text: "StatusQ.Layout" }
StatusNavigationListItem {
title: "Layouts"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.control(title.substring(0, title.length - 1));
title: "Layouts"
selected: page.sourceComponent == layoutComponent
onClicked: page.sourceComponent = layoutComponent
}
StatusListSectionHeadline { text: "StatusQ.Controls" }
StatusNavigationListItem {
title: "Buttons"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.control(title);
title: "Buttons"
selected: page.sourceComponent == buttonsComponent
onClicked: page.sourceComponent = buttonsComponent
}
StatusNavigationListItem {
title: "StatusSwitchTab"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page("StatusTabSwitch");
title: "StatusSwitchTab"
selected: page.sourceComponent == statusTabSwitchesComponent
onClicked: page.sourceComponent = statusTabSwitchesComponent
}
StatusNavigationListItem {
title: "StatusChatCommandButton"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
title: "Controls"
selected: page.sourceComponent == controlsComponent
onClicked: page.sourceComponent = controlsComponent
}
StatusNavigationListItem {
title: "Controls"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.control(title);
}
StatusNavigationListItem {
title: "StatusTabBarIconButton"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusInput"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusSelect"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusAccountSelector"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusAssetSelector"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusColorSelector"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusWalletColorButton"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
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);
title: "StatusInput"
selected: page.sourceComponent == statusInputPageComponent
onClicked: page.sourceComponent = statusInputPageComponent
}
StatusListSectionHeadline { text: "StatusQ.Components" }
StatusNavigationListItem {
title: "StatusAddress"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "List Items"
selected: viewLoader.source.toString().includes(title.replace(/\s+/g, ''))
onClicked: mainPageView.control(title.replace(/\s+/g, ''));
selected: page.sourceComponent == listItemsComponent
onClicked: page.sourceComponent = listItemsComponent
}
StatusNavigationListItem {
title: "StatusChatInfoToolBar"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
selected: page.sourceComponent == chatInfoToolBarComponent
onClicked: page.sourceComponent = chatInfoToolBarComponent
}
StatusNavigationListItem {
title: "Others"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.control(title);
selected: page.sourceComponent == othersComponent
onClicked: page.sourceComponent = othersComponent
}
StatusNavigationListItem {
title: "StatusExpandableItem"
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);
selected: page.sourceComponent == settingsComponent
onClicked: page.sourceComponent = settingsComponent
}
StatusListSectionHeadline { text: "StatusQ.Popup" }
StatusNavigationListItem {
title: "StatusPopupMenu"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
selected: page.sourceComponent == popupMenuComponent
onClicked: page.sourceComponent = popupMenuComponent
}
StatusNavigationListItem {
title: "StatusModal"
selected: viewLoader.source.toString().includes("Popups")
onClicked: mainPageView.control("Popups");
}
StatusListSectionHeadline { text: "StatusQ.Platform" }
StatusNavigationListItem {
title: "StatusMacNotification"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
selected: page.sourceComponent == statusModalComponent
onClicked: page.sourceComponent = statusModalComponent
}
}
}
@@ -306,17 +204,13 @@ StatusWindow {
width: rightPanel.width
anchors.top: parent.top
anchors.topMargin: 64
height: Math.max(rootWindow.height, viewLoader.height + 128)
height: Math.max(rootWindow.height, page.height + 128)
scale: rootWindow.factor
Loader {
id: viewLoader
id: page
active: true
anchors.centerIn: parent
source: mainPageView.control("Icons")
onSourceChanged: {
if (source.toString().includes("Icons")) {
item.iconColor = Theme.palette.primaryColor1;
}
}
sourceComponent: iconsComponent
}
}
}
@@ -347,6 +241,66 @@ StatusWindow {
}
}
Component {
id: iconsComponent
Icons { iconColor: Theme.palette.primaryColor1 }
}
Component {
id: controlsComponent
Controls {}
}
Component {
id: statusInputPageComponent
StatusInputPage {}
}
Component {
id: listItemsComponent
ListItems {}
}
Component {
id: layoutComponent
Layout {}
}
Component {
id: othersComponent
Others {}
}
Component {
id: buttonsComponent
Buttons {}
}
Component {
id: popupMenuComponent
StatusPopupMenuPage {}
}
Component {
id: chatInfoToolBarComponent
StatusChatInfoToolBarPage {}
}
Component {
id: statusModalComponent
Popups {}
}
Component {
id: statusTabSwitchesComponent
StatusTabSwitchPage {}
}
Component {
id: settingsComponent
StatusExpandableSettingsItemPage{}
}
Component {
id: demoAppCmp
@@ -385,7 +339,8 @@ StatusWindow {
}
DemoApp {
id: demoApp
anchors.centerIn: parent
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
DropShadow {
anchors.fill: demoApp
@@ -1,64 +0,0 @@
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
Column {
spacing: 8
StatusAccountSelector {
id: accountSelector
accounts: ListModel {
ListElement {
name: "Pascal"
address: "0x1234567891011"
path: ""
color: "red"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "1199.02"
assets: []
}
ListElement {
name: "Boris"
address: "0x123"
path: ""
color: "red"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "0"
assets: []
}
ListElement {
name: "Alexandra"
address: "0x123"
path: ""
color: "yellow"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "0"
assets: []
}
ListElement {
name: "Khushboo"
address: "0x123"
path: ""
color: "blue"
publicKey: ""
walletType: "generated"
isChat: ""
currencyBalance: "0"
assets: []
}
}
}
}
-25
View File
@@ -1,25 +0,0 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import StatusQ.Components 0.1
import Sandbox 0.1
Column {
spacing: 8
StatusAddress {
text: "0x9ce0056c5fc6bb9459a4dcfa35eaad8c1fee5ce9"
}
Item {
width: 200
height: childrenRect.height
StatusAddress {
text: "0x9ce0056c5fc6bb9459a4dcfa35eaad8c1fee5ce9"
expandable: true
width: parent.width
}
}
}
-40
View File
@@ -1,40 +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.Popups 0.1
import Sandbox 0.1
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"
balance: "20"
symbol: "SNT"
currencyBalance: 9992.01
}
ListElement {
address: "0x1234"
name: "DAI Token"
balance: "15"
symbol: "DAI"
currencyBalance: 20.00001
}
}
}
}
@@ -1,26 +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 Sandbox 0.1
Column {
spacing: 8
StatusChatCommandButton {
icon.name: "send"
icon.color: Theme.palette.miscColor2
text: "Send transaction"
}
StatusChatCommandButton {
icon.name: "send"
icon.rotation: 180
icon.color: Theme.palette.miscColor8
text: "Receive transaction"
}
}
-17
View File
@@ -1,17 +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 Sandbox 0.1
Column {
spacing: 8
StatusColorSelector {
model: ["red", "blue", "green"]
}
}
@@ -1,16 +0,0 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import StatusQ.Platform 0.1
import Sandbox 0.1
Column {
spacing: 8
StatusMacNotification {
name: "Some name"
message: "Some message here"
}
}
@@ -1,38 +0,0 @@
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
}
}
-54
View File
@@ -1,54 +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.Popups 0.1
import Sandbox 0.1
Column {
spacing: 8
StatusSelect {
id: select
label: "Some label"
model: ListModel {
ListElement {
name: "Pascal"
}
ListElement {
name: "Khushboo"
}
ListElement {
name: "Alexandra"
}
ListElement {
name: "Eric"
}
}
selectMenu.delegate: StatusMenuItemDelegate {
statusPopupMenu: select
action: StatusMenuItem {
iconSettings.name: "filled-account"
text: name
onTriggered: {
selectedItem.text = name
}
}
}
selectedItemComponent: Item {
id: selectedItem
anchors.fill: parent
property string text: ""
StatusBaseText {
text: selectedItem.text
anchors.centerIn: parent
color: Theme.palette.directColor1
}
}
}
}
@@ -1,50 +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 Sandbox 0.1
Column {
spacing: 8
Row {
StatusTabBarIconButton {
icon.name: "smileys-and-people"
onClicked: highlighted = !highlighted
}
StatusTabBarIconButton {
icon.name: "animals-and-nature"
onClicked: highlighted = !highlighted
}
StatusTabBarIconButton {
icon.name: "activity"
onClicked: highlighted = !highlighted
}
StatusTabBarIconButton {
icon.name: "travel-and-places"
onClicked: highlighted = !highlighted
}
StatusTabBarIconButton {
icon.name: "objects"
onClicked: highlighted = !highlighted
}
StatusTabBarIconButton {
icon.name: "symbols"
onClicked: highlighted = !highlighted
}
StatusTabBarIconButton {
icon.name: "flags"
onClicked: highlighted = !highlighted
}
}
}
-56
View File
@@ -1,56 +0,0 @@
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("5 USER LIMIT REACHED")
}
}
-40
View File
@@ -1,40 +0,0 @@
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":""},
{"title":"Verification Request Sent", "subTitle":"", "icon":"checkmark-circle", "loading":false, "type":1,"url":""},
{"title":"Collectible is being minted...", "subTitle":"View on Etherscan", "icon":"", "loading":true, "type":0,"url":"http://google.com"},
{"title":"Contact request sent", "subTitle":"", "icon":"checkmark-circle", "loading":false, "type":1,"url":""}
]
delegate: StatusToastMessage {
primaryText: modelData.title
secondaryText: modelData.subTitle
icon.name: modelData.icon
loading: modelData.loading
type: modelData.type
linkUrl: modelData.url
onLinkActivated: {
Qt.openUrlExternally(link);
}
//simulate open
Component.onCompleted: {
open = true;
}
}
}
}
}
@@ -1,38 +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 Sandbox 0.1
Column {
spacing: 8
Row {
spacing: 4
StatusWalletColorButton {
icon.color: Theme.palette.miscColor1
selected: true
}
StatusWalletColorButton {
icon.color: Theme.palette.miscColor2
}
StatusWalletColorButton {
icon.color: Theme.palette.miscColor3
}
StatusWalletColorButton {
icon.color: Theme.palette.miscColor4
}
StatusWalletColorButton {
icon.color: Theme.palette.miscColor5
}
StatusWalletColorButton {
icon.color: Theme.palette.miscColor6
}
StatusWalletColorButton {
icon.color: Theme.palette.miscColor7
}
}
}
@@ -1,17 +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 Sandbox 0.1
Column {
spacing: 8
StatusWalletColorSelect {
model: Theme.palette.accountColors
}
}
-100
View File
@@ -1,100 +0,0 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1
Item {
id: root
width: 800
height: 100
//Simulate animation between steps
property bool stepsCompleted: false
function reset() {
for (var i = 0; i < stepsListModel.count; i++) {
stepsListModel.setProperty(i, "loading", false);
stepsListModel.setProperty(i, "stepCompleted", false);
step1.loadingTime = 0;
step2.loadingTime = 0;
root.stepsCompleted = false;
}
}
ListModel {
id: stepsListModel
ListElement {description:"Send Request"; loadingTime: 0; stepCompleted: false}
ListElement {description:"Receive Response"; loadingTime: 0; stepCompleted: false}
ListElement {description:"Confirm Identity"; loadingTime: 0; stepCompleted: false}
}
Shortcut {
sequence: "Ctrl+R"
onActivated: {
if (!root.stepsCompleted) {
animate.running = true;
} else {
root.reset();
}
}
}
StatusBaseText {
id: indicLabel
anchors.horizontalCenter: parent.horizontalCenter
color: Theme.palette.directColor1
text: "Press Ctrl+R to run the animation"
font.pixelSize: 17
}
SequentialAnimation {
id: animate
ScriptAction {
id: step1
property int loadingTime: 0
Behavior on loadingTime { NumberAnimation { duration: 2000 }}
onLoadingTimeChanged: {
stepsListModel.setProperty(1, "loadingTime", step1.loadingTime);
}
script: {
step1.loadingTime = 2000;
stepsListModel.setProperty(0, "loadingTime", step1.loadingTime);
stepsListModel.setProperty(0, "stepCompleted", true);
}
}
PauseAnimation {
duration: 2100
}
ScriptAction {
id: step2
property int loadingTime: 0
Behavior on loadingTime { NumberAnimation { duration: 2000 } }
onLoadingTimeChanged: {
stepsListModel.setProperty(2, "loadingTime", step2.loadingTime);
}
script: {
step2.loadingTime = 2000;
stepsListModel.setProperty(1, "stepCompleted", true);
}
}
PauseAnimation {
duration: 2100
}
ScriptAction {
script: {
stepsListModel.setProperty(2, "stepCompleted", true);
root.stepsCompleted = true;
}
}
}
//simulation code
StatusWizardStepper {
id: wizardStepper
width: (parent.width - 50)
anchors.top: indicLabel.bottom
anchors.topMargin: 16
anchors.horizontalCenter: parent.horizontalCenter
stepsModel: stepsListModel
}
}
+14 -31
View File
@@ -1,35 +1,18 @@
<RCC>
<qresource prefix="/">
<file>main.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/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>Controls.qml</file>
<file>Icons.qml</file>
<file>Others.qml</file>
<file>Buttons.qml</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>
</qresource>
</RCC>
</RCC>
+12 -18
View File
@@ -1,8 +1,6 @@
QT += quick svg
CONFIG += c++11 warn_on qtquickcompiler
QML_IMPORT_PATH= $$PWD/../src
CONFIG += c++11 warn_on
DEFINES += QT_DEPRECATED_WARNINGS
@@ -15,16 +13,13 @@ 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
@@ -35,18 +30,9 @@ macx {
hunspellTarget.commands = brew install hunspell
QMAKE_EXTRA_TARGETS += hunspellTarget
exists (/usr/local/lib/libhunspell-1.7.a) {
LIBS += -L"/usr/local/lib" -lhunspell-1.7
INCLUDEPATH += /usr/local/include/hunspell
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
LIBS += -L"/usr/local/lib" -lhunspell-1.7
INCLUDEPATH += /usr/local/include/hunspell
}
ios {
@@ -63,6 +49,14 @@ 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 = QUrl::fromLocalFile(applicationDirPath() + "/../main.qml");
const QUrl url(applicationDirPath() + "/../main.qml");
#else
const QUrl url(QStringLiteral("qrc:/main.qml"));
#endif
+7 -14
View File
@@ -1,8 +1,6 @@
#include "spellchecker.h"
#ifdef USE_HUNSPELL
#include "hunspell.hxx"
#endif
#include <QTextCodec>
#include <QFile>
#include <QDebug>
@@ -14,24 +12,22 @@
SpellChecker::SpellChecker(QObject *parent)
: QObject(parent)
, m_userDict("userDict_")
#ifdef USE_HUNSPELL
, m_hunspell(nullptr)
#endif
, m_userDict("userDict_")
{
}
SpellChecker::~SpellChecker()
{
#ifdef USE_HUNSPELL
#ifdef Q_OS_MACOS
delete m_hunspell;
#endif
}
bool SpellChecker::spell(const QString &word)
{
#ifdef USE_HUNSPELL
#ifdef Q_OS_MACOS
return m_hunspell->spell(m_codec->fromUnicode(word).toStdString());
#else
return true;
@@ -40,15 +36,12 @@ bool SpellChecker::spell(const QString &word)
bool SpellChecker::isInit() const
{
#ifdef USE_HUNSPELL
return !m_hunspell;
#endif
return false;
}
void SpellChecker::initHunspell()
{
#ifdef USE_HUNSPELL
#ifdef Q_OS_MACOS
if (m_hunspell) {
delete m_hunspell;
}
@@ -109,7 +102,7 @@ QVariantList SpellChecker::suggest(const QString &word)
{
int numSuggestions = 0;
QVariantList suggestions;
#ifdef USE_HUNSPELL
#ifdef Q_OS_MACOS
std::vector<std::string> wordlist;
wordlist = m_hunspell->suggest(m_codec->fromUnicode(word).toStdString());
@@ -128,14 +121,14 @@ QVariantList SpellChecker::suggest(const QString &word)
void SpellChecker::ignoreWord(const QString &word)
{
#ifdef USE_HUNSPELL
#ifdef Q_OS_MACOS
m_hunspell->add(m_codec->fromUnicode(word).constData());
#endif
}
void SpellChecker::addToUserWordlist(const QString &word)
{
#ifdef USE_HUNSPELL
#ifdef Q_OS_MACOS
QString userDict = m_userDict + m_lang + ".txt";
if (!userDict.isEmpty()) {
QFile userDictonaryFile(userDict);
+2 -2
View File
@@ -6,7 +6,7 @@
#include <QQuickTextDocument>
#include <QSyntaxHighlighter>
#ifdef USE_HUNSPELL
#ifdef Q_OS_MACOS
class Hunspell;
#endif
class QTextCodec;
@@ -45,7 +45,7 @@ private:
QString m_userDict;
QQuickTextDocument *m_document;
#ifdef USE_HUNSPELL
#ifdef Q_OS_MACOS
Hunspell *m_hunspell;
#endif
QTextCodec *m_codec;
-39
View File
@@ -1,39 +0,0 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
StatusBaseText {
id: root
property bool expandable: false
property bool expanded: false
readonly property real actualWidth: implicitWidth
property real maxWidth: width
font.family: Theme.palette.monoFont.name
font.pixelSize: 13
elide: Text.ElideMiddle
color: Theme.palette.baseColor1
Component.onCompleted: {
maxWidth = width
expanded = actualWidth <= maxWidth
}
MouseArea {
anchors.fill: parent
cursorShape: root.expandable ? Qt.PointingHandCursor : Qt.arrowCursor
enabled: root.expandable
onClicked: {
if (root.expanded) {
width = root.width = root.maxWidth
} else {
width = root.width = root.actualWidth
}
root.expanded = !root.expanded
}
}
}
+38 -25
View File
@@ -15,16 +15,17 @@ Column {
width: 288
property string categoryId: ""
property var model: []
property string selectedChatId: ""
property alias chatListItems: delegateModel
property bool draggableItems: false
property alias statusChatListItems: statusChatListItems
property Component popupMenu
property var filterFn
property var profileImageFn
property var chatNameFn
signal chatItemSelected(string categoryId, string id)
signal chatItemSelected(string id)
signal chatItemUnmuted(string id)
signal chatItemReordered(string id, int from, int to)
@@ -36,16 +37,17 @@ 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)
return statusChatList.filterFn(model, statusChatList.categoryId)
}
return true
}
@@ -92,19 +94,31 @@ 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.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
selected: model.active
icon.color: model.color
image.isIdenticon: model.isIdenticon
image.source: model.icon
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
icon.color: model.color || ""
image.isIdenticon: !!!profileImage && !!!model.identityImage && !!model.identicon
image.source: profileImage || model.identityImage || model.identicon || ""
sensor.cursorShape: dragSensor.cursorShape
onClicked: {
@@ -116,7 +130,7 @@ Column {
popupMenuSlot.item.openHandler = function () {
if (!!originalOpenHandler) {
originalOpenHandler(model.itemId)
originalOpenHandler((model.chatId || model.id))
}
}
@@ -129,17 +143,15 @@ Column {
}
}
let p = statusChatListItem.mapToItem(statusChatList, mouse.x, mouse.y)
popupMenuSlot.item.popup(p.x + 4, p.y + 6)
popupMenuSlot.item.popup(mouse.x + 4, statusChatListItem.y + mouse.y + 6)
popupMenuSlot.item.openHandler = originalOpenHandler
return
}
if (!statusChatListItem.selected) {
statusChatList.chatItemSelected(model.parentItemId, model.itemId)
statusChatList.chatItemSelected(model.chatId || model.id)
}
}
onUnmute: statusChatList.chatItemUnmuted(model.itemId)
onUnmute: statusChatList.chatItemUnmuted(model.chatId || model.id)
}
}
@@ -188,8 +200,9 @@ Column {
type: draggable.chatListItem.type
muted: draggable.chatListItem.muted
dragged: true
hasUnreadMessages: model.hasUnreadMessages
notificationsCount: model.notificationsCount
hasUnreadMessages: draggable.chatListItem.hasUnreadMessages
hasMention: draggable.chatListItem.hasMention
badge.value: draggable.chatListItem.badge.value
selected: draggable.chatListItem.selected
icon.color: draggable.chatListItem.icon.color
@@ -20,21 +20,20 @@ Item {
text: "More"
}
property var model: []
property string selectedChatId: ""
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
// Keeps track of expanded category state. Should only be modified
// internally at runtime.
property var openedCategoryState: new Object({})
property Component categoryPopupMenu
property Component chatListPopupMenu
property Component popupMenu
signal chatItemSelected(string categoryId, string id)
signal chatItemSelected(string id)
signal chatItemUnmuted(string id)
signal chatItemReordered(string categoryId, string chatId, int from, int to)
signal chatListCategoryReordered(string categoryId, int from, int to)
@@ -69,25 +68,26 @@ Item {
StatusChatList {
id: statusChatList
anchors.horizontalCenter: parent.horizontalCenter
visible: statusChatList.model.count > 0
onChatItemSelected: statusChatListAndCategories.chatItemSelected(categoryId, id)
visible: chatListItems.count > 0
selectedChatId: statusChatListAndCategories.selectedChatId
onChatItemSelected: statusChatListAndCategories.chatItemSelected(id)
onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id)
onChatItemReordered: statusChatListAndCategories.chatItemReordered(categoryId, id, from, to)
draggableItems: statusChatListAndCategories.draggableItems
model: statusChatListAndCategories.model
filterFn: function (model) {
return !model.isCategory
return !!!model.categoryId
}
popupMenu: statusChatListAndCategories.chatListPopupMenu
}
DelegateModel {
id: delegateModel
model: statusChatListAndCategories.model
delegate: Item {
id: draggable
width: statusChatListCategory.width
height: statusChatListCategory.height
property alias chatListCategory: statusChatListCategory
StatusChatListCategory {
@@ -96,7 +96,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
@@ -133,34 +133,20 @@ Item {
menuButton.tooltip: statusChatListAndCategories.categoryMenuButtonToolTip
originalOrder: model.position
categoryId: model.itemId
categoryId: model.categoryId
name: model.name
showActionButtons: statusChatListAndCategories.showCategoryActionButtons
addButton.onClicked: statusChatListAndCategories.categoryAddButtonClicked(model.itemId)
addButton.onClicked: statusChatListAndCategories.categoryAddButtonClicked(model.categoryId)
chatList.model: model.subItems
chatList.onChatItemSelected: statusChatListAndCategories.chatItemSelected(categoryId, id)
chatList.chatListItems.model: statusChatListAndCategories.chatList.model
chatList.selectedChatId: statusChatListAndCategories.selectedChatId
chatList.onChatItemSelected: statusChatListAndCategories.chatItemSelected(id)
chatList.onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id)
chatList.onChatItemReordered: statusChatListAndCategories.chatItemReordered(model.itemId, id, from, to)
chatList.onChatItemReordered: statusChatListAndCategories.chatItemReordered(model.categoryId, id, from, to)
chatList.draggableItems: statusChatListAndCategories.draggableItems
popupMenu: statusChatListAndCategories.categoryPopupMenu
chatListPopupMenu: statusChatListAndCategories.chatListPopupMenu
// Used to set the initial value of "opened" when the
// model is bound/changed.
opened: {
let openedState = statusChatListAndCategories.openedCategoryState[model.itemId]
return openedState !== undefined ? openedState : true // defaults to open
}
// Used to track the internal changes of the `opened`
// property. This cannot be brought inside the component
// as the state would be lost each time the model is
// changed.
onOpenedChanged: {
statusChatListAndCategories.openedCategoryState[model.itemId] = statusChatListCategory.opened
}
}
DropArea {
@@ -208,7 +194,8 @@ Item {
name: draggable.chatListCategory.name
showActionButtons: draggable.chatListCategory.showActionButtons
chatList.model: draggable.chatListCategory.chatList.model
chatList.chatListItems.model: draggable.chatListCategory.chatList.chatListItems.model
chatList.selectedChatId: draggable.chatListCategory.chatList.selectedChatId
}
}
}
@@ -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) {
@@ -68,7 +68,7 @@ Column {
visible: statusChatListCategory.opened
categoryId: statusChatListCategory.categoryId
filterFn: function (model) {
return !!model.parentItemId && model.parentItemId === statusChatList.categoryId
return !!model.categoryId && model.categoryId == statusChatList.categoryId
}
popupMenu: statusChatListCategory.chatListPopupMenu
+55 -29
View File
@@ -18,17 +18,11 @@ Rectangle {
property string name: ""
property alias badge: statusBadge
property bool hasUnreadMessages: false
property int notificationsCount: 0
property bool hasMention: false
property bool muted: false
property StatusImageSettings image: StatusImageSettings {
width: 24
height: 24
}
property StatusImageSettings image: StatusImageSettings {}
property StatusIconSettings icon: StatusIconSettings {
width: 24
height: 24
color: Theme.palette.miscColor5
letterSize: 15
}
property int type: StatusChatListItem.Type.PublicChat
property bool highlighted: false
@@ -58,7 +52,7 @@ Rectangle {
if (selected) {
return Theme.palette.statusChatListItem.selectedBackgroundColor
}
return hoverHander.hovered || highlighted ? Theme.palette.statusChatListItem.hoverBackgroundColor : Theme.palette.baseColor4
return sensor.containsMouse || highlighted ? Theme.palette.statusChatListItem.hoverBackgroundColor : Theme.palette.baseColor4
}
opacity: dragged ? 0.7 : 1
@@ -66,24 +60,57 @@ Rectangle {
MouseArea {
id: sensor
HoverHandler {
id: hoverHander
}
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled: true
onClicked: statusChatListItem.clicked(mouse)
StatusSmartIdenticon {
Loader {
id: identicon
anchors.left: parent.left
anchors.leftMargin: 8
anchors.verticalCenter: parent.verticalCenter
image: statusChatListItem.image
icon: statusChatListItem.icon
name: statusChatListItem.name
sourceComponent: !!statusChatListItem.image.source.toString() ?
statusRoundedImageCmp : statusLetterIdenticonCmp
}
Component {
id: statusLetterIdenticonCmp
StatusLetterIdenticon {
height: 24
width: 24
name: statusChatListItem.name
letterSize: 15
color: statusChatListItem.icon.color
}
}
Component {
id: statusRoundedImageCmp
Item {
height: 24
width: 24
StatusRoundedImage {
id: statusRoundedImage
width: parent.width
height: parent.height
image.source: statusChatListItem.image.source
showLoadingIndicator: true
color: statusChatListItem.image.isIdenticon ?
Theme.palette.statusRoundedImage.backgroundColor :
"transparent"
border.width: statusChatListItem.image.isIdenticon ? 1 : 0
border.color: Theme.palette.directColor7
}
Loader {
sourceComponent: statusLetterIdenticonCmp
active: statusRoundedImage.image.status === Image.Error
}
}
}
StatusIcon {
@@ -95,15 +122,15 @@ Rectangle {
width: 14
visible: statusChatListItem.type !== StatusChatListItem.Type.OneToOneChat
opacity: {
if (statusChatListItem.muted && !hoverHander.hovered && !statusChatListItem.highlighted) {
if (statusChatListItem.muted && !sensor.containsMouse && !statusChatListItem.highlighted) {
return 0.4
}
return statusChatListItem.hasUnreadMessages ||
statusChatListItem.notificationsCount > 0 ||
return statusChatListItem.hasMention ||
statusChatListItem.hasUnreadMessages ||
statusChatListItem.selected ||
statusChatListItem.highlighted ||
statusBadge.visible ||
hoverHander.hovered ? 1.0 : 0.7
sensor.containsMouse ? 1.0 : 0.7
}
icon: {
@@ -138,19 +165,19 @@ Rectangle {
statusChatListItem.name)
elide: Text.ElideRight
color: {
if (statusChatListItem.muted && !hoverHander.hovered && !statusChatListItem.highlighted) {
if (statusChatListItem.muted && !sensor.containsMouse && !statusChatListItem.highlighted) {
return Theme.palette.directColor5
}
return statusChatListItem.hasUnreadMessages ||
statusChatListItem.notificationsCount > 0 ||
return statusChatListItem.hasMention ||
statusChatListItem.hasUnreadMessages ||
statusChatListItem.selected ||
statusChatListItem.highlighted ||
hoverHander.hovered ||
sensor.containsMouse ||
statusBadge.visible ? Theme.palette.directColor1 : Theme.palette.directColor4
}
font.weight: !statusChatListItem.muted &&
(statusChatListItem.hasUnreadMessages ||
statusChatListItem.notificationsCount > 0 ||
(statusChatListItem.hasMention ||
statusChatListItem.hasUnreadMessages ||
statusBadge.visible) ? Font.Bold : Font.Medium
font.pixelSize: 15
}
@@ -189,8 +216,7 @@ Rectangle {
color: statusChatListItem.muted ? Theme.palette.primaryColor2 : Theme.palette.primaryColor1
border.width: 4
border.color: color
value: statusChatListItem.notificationsCount
visible: statusChatListItem.notificationsCount > 0
visible: statusBadge.value > 0
}
}
}
+9 -19
View File
@@ -93,25 +93,6 @@ Rectangle {
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()
}
@@ -119,6 +100,15 @@ Rectangle {
Loader {
id: popupMenuSlot
active: !!statusChatToolBar.popupMenu
onLoaded: {
popupMenuSlot.item.closeHandler = function () {
menuButton.highlighted = false
}
popupMenuSlot.item.openHandler = function () {
menuButton.highlighted = true
}
}
}
}
+106 -104
View File
@@ -18,8 +18,6 @@ Rectangle {
property bool expanded: false
property StatusIconSettings icon: StatusIconSettings {
width: !!statusExpandableItem.icon.name.toString() ? 24 : 40
height: !!statusExpandableItem.icon.name.toString() ? 24 : 40
color: Theme.palette.directColor1
background: StatusIconBackgroundSettings {
width: 32
@@ -57,129 +55,133 @@ Rectangle {
visible: (statusExpandableItem.type === StatusExpandableItem.Type.Tertiary)
}
Rectangle {
id: header
Loader {
id: identicon
anchors.top: parent.top
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"
anchors.topMargin: 25
anchors.left: parent.left
anchors.leftMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? 0 : 11
active: (statusExpandableItem.type !== StatusExpandableItem.Type.Tertiary)
sourceComponent: !!statusExpandableItem.image.source.toString() ? roundedImage :
!!statusExpandableItem.icon.name.toString() ? roundedIcon : letterIdenticon
}
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
Component {
id: roundedImage
StatusRoundedImage {
image.source: statusExpandableItem.image.source
}
}
Component {
id: roundedIcon
StatusRoundIcon {
icon.background.width: statusExpandableItem.icon.background.width
icon.background.height: statusExpandableItem.icon.background.height
icon.background.color: statusExpandableItem.icon.background.color
icon.color: statusExpandableItem.icon.color
icon.name: statusExpandableItem.icon.name
}
}
Component {
id: letterIdenticon
StatusLetterIdenticon {
height: 40
width: 40
name: primaryText.text
active: (statusExpandableItem.type !== StatusExpandableItem.Type.Tertiary)
letterSize: 20
color: Theme.palette.miscColor5
}
}
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
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
anchors.verticalCenter: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? identicon.verticalCenter : undefined
anchors.verticalCenter: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? identicon.verticalCenter : undefined
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)
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)
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.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
}
StatusBaseText {
id: secondaryText
anchors.top: primaryText.bottom
anchors.topMargin: 4
anchors.left: primaryText.left
anchors.right: primaryText.right
StatusBaseText {
id: secondaryText
anchors.top: primaryText.bottom
anchors.topMargin: 4
anchors.left: primaryText.left
anchors.right: primaryText.right
font.pixelSize: 15
lineHeight: 22
lineHeightMode: Text.FixedHeight
elide: Text.ElideRight
color: Theme.palette.directColor3
}
font.pixelSize: 15
lineHeight: 22
lineHeightMode: Text.FixedHeight
elide: Text.ElideRight
color: Theme.palette.directColor3
}
StatusBaseText {
id: additionalText
anchors.verticalCenter: primaryText.verticalCenter
anchors.verticalCenterOffset: 2
anchors.right: expandImage.left
anchors.rightMargin: 16
StatusBaseText {
id: additionalText
anchors.verticalCenter: primaryText.verticalCenter
anchors.verticalCenterOffset: 2
anchors.right: expandImage.left
anchors.rightMargin: 16
font.pixelSize: 15
lineHeight: 24
lineHeightMode: Text.FixedHeight
elide: Text.ElideRight
color: Theme.palette.baseColor1
}
font.pixelSize: 15
lineHeight: 24
lineHeightMode: Text.FixedHeight
elide: Text.ElideRight
color: Theme.palette.baseColor1
}
StatusButton {
id: button
anchors.top: parent.top
anchors.topMargin: 19
anchors.right: parent.right
anchors.rightMargin: 16
visible: !!text
}
StatusButton {
id: button
anchors.top: parent.top
anchors.topMargin: 19
anchors.right: parent.right
anchors.rightMargin: 16
visible: !!text
}
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
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
}
}
MouseArea {
anchors.fill: parent
onClicked: {
if(expandable) {
expanded = !expanded
}
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: header.bottom
anchors.top: !!secondaryText.text ? secondaryText.bottom: primaryText.bottom
anchors.topMargin: 16
anchors.left: parent.left
anchors.leftMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 48 : 0
+84 -105
View File
@@ -9,29 +9,49 @@ 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 bool titleIcon1Visible
property bool titleIcon2Visible
property string subTitle: ""
property string tertiaryTitle: ""
property string label: ""
property string tertiaryTitle: ""
property alias badge: statusListItemBadge
property real leftPadding: 16
property real rightPadding: 16
property bool enabled: true
property bool highlighted: false
property int type: StatusListItem.Type.Primary
property list<Item> components
property StatusIconSettings icon: StatusIconSettings {
height: isLetterIdenticon ? 40 : 20
width: isLetterIdenticon ? 40 : 20
height: 20
width: 20
rotation: 0
isLetterIdenticon: false
letterSize: 21
color: isLetterIdenticon ? background.color : type === StatusListItem.Type.Danger ?
color: type === StatusListItem.Type.Danger ?
Theme.palette.dangerColor1 : Theme.palette.primaryColor1
background: StatusIconBackgroundSettings {
width: 40
@@ -52,69 +72,23 @@ Rectangle {
height: 40
isIdenticon: false
}
property StatusIconSettings titleIcon1: StatusIconSettings {
width: dummyImage.width
height: dummyImage.height
background: StatusIconBackgroundSettings {
width: 10
height: 10
}
// Only used to get implicit width and height from the actual image
property Image dummyImage: Image {
source: titleIcon1.name ? "../../assets/img/icons/" + titleIcon1.name + ".svg": ""
visible: false
}
}
property StatusIconSettings titleIcon2: StatusIconSettings {
width: dummyImage.width
height: dummyImage.height
background: StatusIconBackgroundSettings {
width: 10
height: 10
}
// Only used to get implicit width and height from the actual image
property Image dummyImage: Image {
source: titleIcon2.name ? "../../assets/img/icons/" + titleIcon2.name + ".svg": ""
visible: false
}
}
property string label: ""
property int type: StatusListItem.Type.Primary
property alias sensor: sensor
property alias badge: statusListItemBadge
property alias statusListItemIcon: iconOrImage
property alias statusListItemTitle: statusListItemTitle
property alias statusListItemTitleAside: statusListItemTitleAsideText
property alias statusListItemTitleArea: statusListItemTitleArea
property alias statusListItemSubTitle: statusListItemSubTitle
property alias statusListItemTertiaryTitle: statusListItemTertiaryTitle
property alias statusListItemComponentsSlot: statusListItemComponentsSlot
property list<Item> components
signal clicked(string itemId)
signal titleClicked(string titleId)
enum Type {
Primary,
Secondary,
Danger
}
implicitWidth: 448
implicitHeight: Math.max(64, statusListItemTitleArea.height + 16)
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) {
@@ -131,25 +105,65 @@ Rectangle {
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled: true
preventStealing: true
onClicked: {
statusListItem.clicked(statusListItem.itemId)
}
StatusSmartIdenticon {
Loader {
id: iconOrImage
anchors.left: parent.left
anchors.leftMargin: statusListItem.leftPadding
anchors.top: parent.top
anchors.topMargin: 12
image: statusListItem.image
icon: statusListItem.icon
name: statusListItem.title
sourceComponent: {
if (statusListItem.icon.isLetterIdenticon) {
return statusLetterIdenticon
}
return !!statusListItem.icon.name ? statusRoundedIcon : statusRoundedImage
}
active: statusListItem.icon.isLetterIdenticon ||
!!statusListItem.icon.name ||
!!statusListItem.image.source.toString()
badge.border.color: statusListItem.color
}
Component {
id: statusRoundedIcon
StatusRoundIcon {
icon.width: statusListItem.icon.width
icon.height: statusListItem.icon.height
icon.name: statusListItem.icon.name
icon.rotation: statusListItem.icon.rotation
icon.color: statusListItem.icon.color
color: statusListItem.icon.background.color
width: statusListItem.icon.background.width
height: statusListItem.icon.background.height
}
}
Component {
id: statusRoundedImage
StatusRoundedImage {
image.source: statusListItem.image.source
image.height: statusListItem.image.height
image.width: statusListItem.image.width
color: statusListItem.image.isIdenticon ?
Theme.palette.statusRoundedImage.backgroundColor :
"transparent"
border.width: statusListItem.image.isIdenticon ? 1 : 0
border.color: Theme.palette.directColor7
}
}
Component {
id: statusLetterIdenticon
StatusLetterIdenticon {
width: statusListItem.icon.background.width
height: statusListItem.icon.background.height
color: statusListItem.icon.background.color
name: statusListItem.title
}
}
Item {
@@ -168,9 +182,6 @@ Rectangle {
font.pixelSize: 15
height: visible ? contentHeight : 0
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
anchors.left: parent.left
anchors.right: !statusListItem.titleAsideText && !statusListItem.titleIcon1Visible && !statusListItem.titleIcon2Visible
? parent.right : undefined
color: {
if (!statusListItem.enabled) {
return Theme.palette.baseColor1
@@ -208,38 +219,6 @@ Rectangle {
visible: !!statusListItem.titleAsideText
}
Row {
id: titleIconsRow
spacing: 4
anchors.left: !statusListItem.titleAsideText ? statusListItemTitle.right : statusListItemTitleAsideText.right
anchors.verticalCenter: statusListItemTitle.verticalCenter
anchors.leftMargin: titleIconsRow.spacing
StatusRoundIcon {
visible: statusListItem.titleIcon1Visible
icon.name: statusListItem.titleIcon1.name
icon.width: statusListItem.titleIcon1.width
icon.height: statusListItem.titleIcon1.height
icon.rotation: statusListItem.titleIcon1.rotation
icon.color: statusListItem.titleIcon1.color
icon.background.color: statusListItem.titleIcon1.background.color
icon.background.width: statusListItem.titleIcon1.background.width
icon.background.height: statusListItem.titleIcon1.background.height
}
StatusRoundIcon {
visible: statusListItem.titleIcon2Visible
icon.name: statusListItem.titleIcon2.name
icon.width: statusListItem.titleIcon2.width
icon.height: statusListItem.titleIcon2.height
icon.rotation: statusListItem.titleIcon2.rotation
icon.color: statusListItem.titleIcon2.color
icon.background.color: statusListItem.titleIcon2.background.color
icon.background.width: statusListItem.titleIcon2.background.width
icon.background.height: statusListItem.titleIcon2.background.height
}
}
StatusBaseText {
id: statusListItemSubTitle
anchors.top: statusListItemTitle.bottom
@@ -1,76 +0,0 @@
import QtQuick 2.0
import StatusQ.Core.Theme 0.1
import StatusQ.Core 0.1
StatusListItem {
id: root
property string nickName: ""
property string userName: ""
property string chatKey: ""
property bool isMutualContact: false
property var trustIndicator: StatusMemberListItem.TrustedType.None
property bool isOnline: false
enum TrustedType {
None, //0
Verified, //1
Untrustworthy //2
}
// Subtitle composition:
function composeSubtitile() {
var compose = ""
if(root.userName !== "")
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
titleIcon1Visible: root.isMutualContact
titleIcon2Visible: root.trustIndicator !== StatusMemberListItem.TrustedType.None
subTitle: 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
// Trusted type icons definition:
titleIcon1.name: "tiny/tiny-contact"
titleIcon1.color: Theme.palette.indirectColor1
titleIcon1.background.color: Theme.palette.primaryColor1
// None and Untrustworthy types, same aspect (Icon will not be visible in case of None type):
titleIcon2.name: trustIndicator === StatusMemberListItem.TrustedType.Verified ? "tiny/tiny-checkmark" : "tiny/subtract"
titleIcon2.color: Theme.palette.indirectColor1
titleIcon2.background.color: trustIndicator === StatusMemberListItem.TrustedType.Verified ? Theme.palette.primaryColor1 : Theme.palette.dangerColor1
}
-211
View File
@@ -1,211 +0,0 @@
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
}
enum ContactType {
STANDARD = 0,
RENAME = 1,
CONTACT = 2,
VERIFIED = 3,
UNTRUSTWORTHY = 4
}
property alias messageHeader: messageHeader
property alias quickActions:quickActionsPanel.quickActions
property alias statusChatInput: editComponent.inputComponent
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
icon1.name: messageDetails.contactType === StatusMessage.ContactType.CONTACT ? "tiny/tiny-contact" : ""
icon2.name: messageDetails.contactType === StatusMessage.ContactType.VERIFIED ? "tiny/tiny-checkmark" :
messageDetails.contactType === StatusMessage.ContactType.UNTRUSTWORTHY ? "tiny/subtract": ""
icon2.background.color: messageDetails.contactType === StatusMessage.ContactType.UNTRUSTWORTHY ? Theme.palette.dangerColor1 : Theme.palette.primaryColor1
icon2.color: Theme.palette.indirectColor1
resendText: statusMessage.resendText
showResendButton: messageDetails.hasExpired && messageDetails.amISender
onClicked: statusMessage.senderNameClicked()
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
}
}
@@ -1,28 +0,0 @@
import QtQuick 2.13
import StatusQ.Core 0.1
QtObject {
id: msgDetails
property bool amISender: false
property string displayName: ""
property string secondaryName: ""
property string chatID: ""
property StatusImageSettings profileImage: StatusImageSettings {
width: 40
height: 40
}
property bool isEdited: false
property string messageText: ""
property int contentType: 0
property string messageContent: ""
property int contactType: 0
property bool hasMention: false
property bool isPinned: false
property string pinnedBy: ""
property bool hasExpired: false
property string timestamp: ""
}
@@ -1,93 +0,0 @@
import QtQuick 2.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Loader {
id: statusSmartIdenticon
property string name: ""
// Badge color properties must be set if badgeItem.visible = true
property alias badge: statusBadge
property StatusIconSettings icon: StatusIconSettings {
width: 40
height: 40
}
property StatusImageSettings image: StatusImageSettings {
width: 40
height: 40
}
sourceComponent: statusSmartIdenticon.icon.isLetterIdenticon ? letterIdenticon :
!!statusSmartIdenticon.image.source.toString() ? roundedImage :
!!statusSmartIdenticon.icon.name.toString() ? roundedIcon : letterIdenticon
Component {
id: roundedImage
Item {
width: statusSmartIdenticon.image.width
height: statusSmartIdenticon.image.height
StatusRoundedImage {
id: statusRoundImage
width: parent.width
height: parent.height
image.source: statusSmartIdenticon.image.source
showLoadingIndicator: true
border.width: statusSmartIdenticon.image.isIdenticon ? 1 : 0
border.color: Theme.palette.directColor7
color: statusSmartIdenticon.image.isIdenticon ?
Theme.palette.statusRoundedImage.backgroundColor :
"transparent"
}
Loader {
anchors.centerIn: parent
active: statusRoundImage.image.status === Image.Error
sourceComponent: letterIdenticon
onLoaded: {
item.color = Theme.palette.miscColor5
item.width = statusSmartIdenticon.image.width
item.height = statusSmartIdenticon.image.height
}
}
}
}
Component {
id: roundedIcon
StatusRoundIcon {
icon.background.width: statusSmartIdenticon.icon.background.width
icon.background.height: statusSmartIdenticon.icon.background.height
icon.background.color: statusSmartIdenticon.icon.background.color
icon.width: statusSmartIdenticon.icon.width
icon.height: statusSmartIdenticon.icon.height
icon.name: statusSmartIdenticon.icon.name
icon.rotation: statusSmartIdenticon.icon.rotation
icon.color: statusSmartIdenticon.icon.color
}
}
Component {
id: letterIdenticon
StatusLetterIdenticon {
width: statusSmartIdenticon.icon.width
height: statusSmartIdenticon.icon.height
color: statusSmartIdenticon.icon.color
name: statusSmartIdenticon.name
letterSize: statusSmartIdenticon.icon.letterSize
}
}
// State component
StatusBadge {
id: statusBadge
visible: false
anchors.bottom: statusSmartIdenticon.bottom
anchors.right: statusSmartIdenticon.right
border.width: 3
implicitHeight: 15
implicitWidth: 15
z: 100
}
}
@@ -1,126 +0,0 @@
import QtQuick 2.14
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Item {
id: root
implicitWidth: 448
implicitHeight: 44
property alias textEdit: edit
property alias text: edit.text
property string warningText: ""
property string toLabelText: ""
property int nameCountLimit: 5
property ListModel namesModel: ListModel { }
function find(model, criteria) {
for (var i = 0; i < model.count; ++i) if (criteria(model.get(i))) return model.get(i);
return null;
}
function insertTag(name, id) {
if (!find(namesModel, function(item) { return item.publicId === id }) && namesModel.count < root.nameCountLimit) {
namesModel.insert(namesModel.count, {"name": name, "publicId": id});
edit.clear();
}
}
Rectangle {
anchors.fill: parent
radius: 8
color: Theme.palette.baseColor2
RowLayout {
anchors.fill: parent
anchors.leftMargin: 16
anchors.rightMargin: 16
spacing: 8
StatusBaseText {
Layout.preferredWidth: 22
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
color: Theme.palette.baseColor1
text: root.toLabelText
}
ListView {
id: namesList
Layout.preferredWidth: (count >= 5) ? (parent.width - warningTextLabel.width - 30) : childrenRect.width
implicitHeight: 30
visible: (count > 0)
Layout.alignment: Qt.AlignVCenter
model: namesModel
orientation: ListView.Horizontal
spacing: 8
clip: true
onWidthChanged: {
positionViewAtEnd();
}
delegate: Rectangle {
id: nameDelegate
width: (nameText.contentWidth + 34)
height: 30
color: mouseArea.containsMouse ? Theme.palette.miscColor1 : Theme.palette.primaryColor1
radius: 8
StatusBaseText {
id: nameText
anchors.left: parent.left
anchors.leftMargin: 8
anchors.verticalCenter: parent.verticalCenter
color: Theme.palette.indirectColor1
text: name
}
StatusIcon {
anchors.left: nameText.right
anchors.verticalCenter: parent.verticalCenter
color: Theme.palette.indirectColor1
icon: "close"
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
namesModel.remove(index, 1);
}
}
}
}
TextEdit {
id: edit
Layout.fillWidth: true
Layout.preferredHeight: 44
verticalAlignment: Text.AlignVCenter
visible: (namesModel.count < 5)
enabled: visible
focus: true
font.pixelSize: 15
font.family: Theme.palette.baseFont.name
color: Theme.palette.directColor1
Keys.onPressed: {
if ((event.key === Qt.Key_Backspace || event.key === Qt.Key_Escape)
&& getText(cursorPosition, (cursorPosition-1)) === "") {
namesModel.remove((namesList.count-1), 1);
}
}
}
StatusBaseText {
id: warningTextLabel
visible: (namesModel.count === 5)
Layout.preferredWidth: 120
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
font.pixelSize: 10
color: Theme.palette.dangerColor1
text: root.warningText
}
}
}
}
@@ -1,182 +0,0 @@
import QtQuick 2.14
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtGraphicalEffects 1.13
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
Control {
id: root
width: 343
height: !!secondaryText ? 68 : 48
anchors.right: parent.right
property bool open: false
property string primaryText: ""
property string secondaryText: ""
property bool loading: false
property string iconName: ""
property string linkUrl: ""
property StatusIconSettings icon: StatusIconSettings {
width: 23
height: 23
}
property int type: StatusToastMessage.Type.Default
enum Type {
Default,
Success
}
function open(title, subTitle, iconName, type, loading, url) {
root.primaryText = title;
root.secondaryText = subTitle;
root.icon.name = iconName;
root.type = type;
root.loading = loading;
root.linkUrl = url;
root.open = true;
}
signal close()
signal linkActivated(var link)
states: [
State {
name: "opened"
when: root.open
PropertyChanges {
target: root
anchors.rightMargin: 0
opacity: 1.0
}
},
State {
name: "closed"
when: !root.open
PropertyChanges {
target: root
anchors.rightMargin: -width
opacity: 0.0
}
StateChangeScript {
script: { root.close(); }
}
}
]
transitions: [
Transition {
to: "*"
NumberAnimation { properties: "anchors.rightMargin,opacity"; duration: 400 }
}
]
background: Rectangle {
id: background
anchors.fill: parent
color: Theme.palette.statusToastMessage.backgroundColor
radius: 8
border.color: Theme.palette.baseColor2
layer.enabled: true
layer.effect: DropShadow {
verticalOffset: 3
radius: 8
samples: 15
fast: true
cached: true
color: Theme.palette.dropShadow
}
}
contentItem: Item {
anchors.left: parent.left
anchors.leftMargin: 16
anchors.right: parent.right
anchors.rightMargin: 4
height: parent.height
MouseArea {
anchors.fill: parent
onMouseXChanged: {
root.open = (mouseX < (root.width/3));
}
}
RowLayout {
anchors.fill: parent
spacing: 16
Rectangle {
implicitWidth: 32
implicitHeight: 32
Layout.alignment: Qt.AlignVCenter
radius: (root.width/2)
color: (root.type === StatusToastMessage.Type.Success) ?
Theme.palette.successColor2 : Theme.palette.primaryColor3
Loader {
anchors.centerIn: parent
sourceComponent: root.loading ? loadingInd : statusIcon
Component {
id: loadingInd
StatusLoadingIndicator {
color: (root.type === StatusToastMessage.Type.Success) ?
Theme.palette.successColor1 : Theme.palette.primaryColor1
}
}
Component {
id: statusIcon
StatusIcon {
anchors.centerIn: parent
width: root.icon.width
height: root.icon.height
color: (root.type === StatusToastMessage.Type.Success) ?
Theme.palette.successColor1 : Theme.palette.primaryColor1
icon: root.icon.name
}
}
}
}
Column {
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
StatusBaseText {
width: parent.width
font.pixelSize: 13
color: Theme.palette.directColor1
elide: Text.ElideRight
text: root.primaryText
}
StatusBaseText {
width: parent.width
visible: (!root.linkUrl && !!root.secondaryText)
height: visible ? contentHeight : 0
font.pixelSize: 13
color: Theme.palette.baseColor1
text: root.secondaryText
elide: Text.ElideRight
}
StatusSelectableText {
visible: (!!root.linkUrl)
height: visible ? implicitHeight : 0
font.pixelSize: 13
hoveredLinkColor: Theme.palette.primaryColor1
text: "<p><a style=\"text-decoration:none\" href=\'" + root.linkUrl + " \'>" + root.secondaryText + "</a></p>"
onLinkActivated: {
root.linkActivated(root.linkUrl);
}
}
}
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
icon.name: "close"
icon.color: Theme.palette.directColor1
implicitWidth: 30
implicitHeight: 30
onClicked: {
root.open = false;
}
}
}
}
}
@@ -1,78 +0,0 @@
import QtQuick 2.14
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.14
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
Item {
id: wizardWrapper
width: parent.width
height: 56
property ListModel stepsModel: ListModel { }
ListView {
id: repeat
width: childrenRect.width
height: parent.height
anchors.horizontalCenter: parent.horizontalCenter
orientation: ListView.Horizontal
model: stepsModel
delegate: Item {
id: wrapperItem
width: (index === 0) ? descriptionLabel.contentWidth : (wizardWrapper.width / repeat.count)
height: 56
onXChanged: {
//as x changes while delegates are created, direct assignment doesn't work
x = (index === (repeat.count-1)) ? (width+32) : (label.width/2) + 8
}
StatusProgressBar {
id: barBorder
width: visible ? (parent.width - (label.width/2 + 24)) : 0
height: visible ? 8 : 0
visible: (index > 0)
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -12
from: 0
//TODO what is to: here?
to: 2000
value: loadingTime
backgroundColor: "transparent"
backgroundBorderColor: Theme.palette.primaryColor1
fillColor: Theme.palette.primaryColor1
}
Item {
id: label
width: descriptionLabel.contentWidth
height: 56
anchors.left: (index > 0) ? barBorder.right : parent.left
anchors.leftMargin: (index > 0) ? -((width/2) - 24) : 0
Rectangle {
width: 32
height: 32
anchors.horizontalCenter: parent.horizontalCenter
radius: width/2
color: stepCompleted ? Theme.palette.primaryColor1 : "transparent"
border.color: (stepCompleted && (barBorder.visible ? (barBorder.value === barBorder.to) : true))
? "transparent" : Theme.palette.primaryColor1
border.width: 2
StatusBaseText {
anchors.centerIn: parent
text: index+1
font.pixelSize: 17
color: (stepCompleted && (barBorder.visible ? (barBorder.value === barBorder.to) : true))
? Theme.palette.indirectColor1 : Theme.palette.primaryColor1
}
}
StatusBaseText {
id: descriptionLabel
anchors.bottom: parent.bottom
text: description
color: Theme.palette.directColor1
font.pixelSize: 13
}
}
}
}
}
@@ -1,143 +0,0 @@
import QtQuick 2.3
import QtMultimedia 5.14
import QtQuick.Layouts 1.14
import StatusQ.Controls 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
// To-do update as per latest design -> Audio graphs. Also the player should ideally be in the BE?
Rectangle {
id: audioChatMessage
property string audioMessageInfoText: ""
property bool isPreview: false
property bool hovered: false
property string audioSource: ""
width: 320
height: 32
radius: 20
color: hovered ? Theme.palette.directColor8 : Theme.palette.baseColor2
Audio {
id: audioMessage
source: audioSource
notifyInterval: 150
}
RowLayout {
id: preview
visible: isPreview
spacing: 5
anchors.centerIn: parent
StatusIcon {
id: icon
Layout.alignment: Qt.AlignVCenter
Layout.preferredWidth: 14
Layout.preferredHeight: 14
icon: "audio"
color: Theme.palette.baseColor1
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
color: Theme.palette.baseColor1
text: audioMessageInfoText
font.pixelSize: 13
}
}
StatusFlatRoundButton {
id: playButton
width: 15
height: 15
anchors.left: parent.left
anchors.leftMargin: 16
anchors.verticalCenter: parent.verticalCenter
visible: !isPreview
type: StatusFlatRoundButton.Type.Tertiary
color: "transparent"
icon.name: audioMessage.playbackState == Audio.PlayingState ? "pause-filled" : "play-filled"
icon.color: Theme.palette.directColor1
onClicked: {
if(audioMessage.playbackState === Audio.PlayingState){
audioMessage.pause();
} else {
audioMessage.play();
}
}
}
Rectangle {
height: 2
width: 240
color: Theme.palette.directColor5
anchors.verticalCenter: parent.verticalCenter
anchors.left: playButton.right
anchors.leftMargin: 10
visible: !isPreview
Rectangle {
id: progress
height: 2
width: {
if(audioMessage.duration === 0) return 0;
if(audioMessage.playbackState === Audio.StoppedState) return 0;
return parent.width * audioMessage.position / audioMessage.duration;
}
color: Theme.palette.directColor5
anchors.verticalCenter: parent.verticalCenter
}
Rectangle {
id: handle
width: 10
height: 10
color: Theme.palette.directColor1
radius: 10
anchors.verticalCenter: parent.verticalCenter
x: progress.width
state: "default"
states: State {
name: "pressed"
when: handleMouseArea.pressed
PropertyChanges {
target: handle;
scale: 1.2
}
}
transitions: Transition {
NumberAnimation {
properties: "scale";
duration: 100;
easing.type: Easing.InOutQuad
}
}
MouseArea {
id: handleMouseArea
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
drag.target: parent
drag.axis: Drag.XAxis
drag.minimumX: 0
drag.maximumX: parent.parent.width
onPressed: {
handle.state = "pressed"
if(audioMessage.playbackState === Audio.PlayingState) {
audioMessage.pause();
}
}
onReleased: {
handle.state = "default"
audioMessage.seek(audioMessage.duration * handle.x / parent.parent.width)
audioMessage.play()
}
}
}
}
}
@@ -1,51 +0,0 @@
import QtQuick 2.3
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
Item {
id: editText
property alias inputComponent: chatInputLoader.sourceComponent
property string cancelButtonText: ""
property string saveButtonText: ""
property string msgText: ""
signal cancelEditClicked()
signal editCompleted(var newMsgText)
height: childrenRect.height
ColumnLayout {
spacing: 4
Loader {
id: chatInputLoader
// To-Do: Move to StatusChatInput once its moved to StatusQ
sourceComponent: StatusInput {
width: editText.width
input.placeholderText: ""
input.text: msgText
input.implicitHeight: 40
}
}
RowLayout {
spacing: 4
StatusFlatButton {
id: cancelBtn
text: cancelButtonText
size: StatusBaseButton.Size.Small
onClicked: cancelEditClicked()
}
StatusButton {
id: saveBtn
text: saveButtonText
size: StatusBaseButton.Size.Small
enabled: chatInputLoader.item.input.text.trim().length > 0
onClicked: editCompleted(chatInputLoader.item.input.text)
}
}
}
}
@@ -1,114 +0,0 @@
import QtQuick 2.3
import QtGraphicalEffects 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Item {
id: imageContainer
enum ShapeType {
ROUNDED = 0,
LEFT_ROUNDED = 1,
RIGHT_ROUNDED = 2
}
property alias imageAlias: imageMessage
property bool isAppWindowActive: false
property url source: ""
property bool allCornersRounded: false
property bool isLeftCorner: true
property int imageWidth: 350
property int shapeType: -1
property string loadingImageText: ""
property string errorLoadingImageText: ""
signal clicked(var image, var mouse)
width: loadingImage.visible ? loadingImage.width : imageMessage.width
height: loadingImage.visible ? loadingImage.height : imageMessage.paintedHeight
QtObject {
id: _internal
property bool isAnimated: !!source && source.toString().endsWith('.gif')
property bool pausePlaying: false
}
AnimatedImage {
id: imageMessage
width: sourceSize.width > imageWidth ? imageWidth : sourceSize.width
fillMode: Image.PreserveAspectFit
source: imageContainer.source
playing: _internal.isAnimated && isAppWindowActive && !_internal.pausePlaying
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Item {
width: imageMessage.width
height: imageMessage.height
Rectangle {
anchors.top: parent.top
anchors.left: parent.left
width: imageMessage.width
height: imageMessage.height
radius: 16
}
Rectangle {
anchors.bottom: parent.bottom
anchors.left: parent.left
width: 32
height: 32
radius: 4
visible: shapeType === StatusImageMessage.ShapeType.LEFT_ROUNDED //!isLeftCorner && !allCornersRounded
}
Rectangle {
anchors.bottom: parent.bottom
anchors.right: parent.right
width: 32
height: 32
radius: 4
visible: shapeType === StatusImageMessage.ShapeType.RIGHT_ROUNDED //isLeftCorner && !allCornersRounded
}
}
}
MouseArea {
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
onClicked: {
if (imageContainer.isAnimated) {
// FIXME the ListView completely removes Items that scroll out of view
// so when we scroll backto the image, it gets reloaded and playing is reset
_internal.pausePlaying = ! _internal.pausePlaying
return
}
imageContainer.clicked(imageMessage, mouse)
}
}
}
Rectangle {
id: loadingImage
visible: imageMessage.status === Image.Loading
|| imageMessage.status === Image.Error
width: parent.width
height: width
border.width: 1
border.color: Theme.palette.baseColor2
radius: 8
StatusBaseText {
anchors.centerIn: parent
text: imageMessage.status === Image.Error ? errorLoadingImageText: loadingImageText
color: imageMessage.status === Image.Error?
Theme.palette.dangerColor1 :
Theme.palette.directColor1
font.pixelSize: 15
}
}
}
@@ -1,158 +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
import StatusQ.Controls 0.1
Item {
id: statusMessageHeader
property alias displayNameLabel: primaryDisplayName
property alias secondaryNameLabel: secondaryDisplayName
property alias tertiaryDetailsLabel: tertiaryDetailText
property alias timestamp: timestampText
property string displayName: ""
property string secondaryName: ""
property string tertiaryDetail: ""
property string resendText: ""
property bool showResendButton: false
property StatusIconSettings icon1: StatusIconSettings {
width: dummyImage.width
height: dummyImage.height
rotation: 0
color: Theme.palette.indirectColor1
background: StatusIconBackgroundSettings {
width: 10
height: 10
color: Theme.palette.primaryColor1
}
// only used to get implicit width and height from the actual image
property Image dummyImage: Image {
source: icon1.name ? "../../../../assets/img/icons/" + icon1.name + ".svg": ""
visible: false
}
}
property StatusIconSettings icon2: StatusIconSettings {
width: dummyImage.width
height: dummyImage.height
rotation: 0
color: Theme.palette.primaryColor1
background: StatusIconBackgroundSettings {
width: 10
height: 10
color: Theme.palette.indirectColor1
}
// only used to get implicit width and height from the actual image
property Image dummyImage: Image {
source: icon2.name ? "../../../../assets/img/icons/" + icon2.name + ".svg": ""
visible: false
}
}
signal clicked()
signal resendClicked()
height: childrenRect.height
width: primaryDisplayName.width + (secondaryDisplayName.visible ? secondaryDisplayName.width + header.spacing : 0)
RowLayout {
id: header
spacing: 4
TextEdit {
id: primaryDisplayName
font.family: Theme.palette.baseFont.name
font.weight: Font.Medium
font.pixelSize: 15
font.underline: mouseArea.containsMouse
readOnly: true
wrapMode: Text.WordWrap
selectByMouse: true
color: Theme.palette.primaryColor1
text: displayName
MouseArea {
id: mouseArea
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled: true
onClicked: {
statusMessageHeader.clicked()
}
}
Layout.alignment: Qt.AlignBottom
}
StatusRoundIcon {
icon.background.width: icon1.background.width
icon.background.height: icon1.background.height
icon.background.color: icon1.background.color
icon.width: icon1.width
icon.height: icon1.height
icon.name: icon1.name
icon.rotation: icon1.rotation
icon.color: icon1.color
visible: !!icon.name
}
StatusRoundIcon {
icon.background.width: icon2.background.width
icon.background.height: icon2.background.height
icon.background.color: icon2.background.color
icon.width: icon2.width
icon.height: icon2.height
icon.name: icon2.name
icon.rotation: icon2.rotation
icon.color: icon2.color
visible: !!icon.name
}
StatusBaseText {
id: secondaryDisplayName
Layout.alignment: Qt.AlignVCenter
color: Theme.palette.baseColor1
font.pixelSize: 10
text: secondaryName
visible: !!text
}
StatusBaseText {
id: dotSeparator1
Layout.fillHeight: true
font.pixelSize: 10
color: Theme.palette.baseColor1
text: "."
visible: secondaryDisplayName.visible
}
StatusBaseText {
id: tertiaryDetailText
Layout.alignment: Qt.AlignVCenter
Layout.maximumWidth: 58
font.pixelSize: 10
elide: Text.ElideMiddle
color: Theme.palette.baseColor1
text: tertiaryDetail
}
StatusBaseText {
id: dotSeparator2
Layout.fillHeight: true
font.pixelSize: 10
color: Theme.palette.baseColor1
text: "."
visible: tertiaryDetailText.visible
}
StatusTimeStampLabel {
id: timestampText
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
color: Theme.palette.dangerColor1
font.pixelSize: 12
text: statusMessageHeader.resendText
visible: showResendButton && !!timestampText.text
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: statusMessageHeader.resendClicked()
}
}
}
}
@@ -1,51 +0,0 @@
import QtQuick 2.13
import QtGraphicalEffects 1.13
import QtQuick.Layouts 1.14
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
Rectangle {
id: buttonsContainer
property list<Item> quickActions
QtObject {
id: _internal
readonly property int containerMargin: 2
}
width: buttonRow.width + _internal.containerMargin * 2
height: 36
radius: 8
color: Theme.palette.statusSelect.menuItemBackgroundColor
layer.enabled: true
layer.effect: DropShadow {
width: buttonsContainer.width
height: buttonsContainer.height
x: buttonsContainer.x
y: buttonsContainer.y + 10
horizontalOffset: 0
verticalOffset: 2
source: buttonsContainer
radius: 10
samples: 15
color: Theme.palette.dropShadow
}
Row {
id: buttonRow
spacing: _internal.containerMargin
anchors.left: parent.left
anchors.leftMargin: _internal.containerMargin
anchors.verticalCenter: buttonsContainer.verticalCenter
height: parent.height - 2 * _internal.containerMargin
}
onQuickActionsChanged: {
for (let idx in quickActions) {
quickActions[idx].parent = buttonRow
}
}
}
@@ -1,125 +0,0 @@
import QtQuick 2.14
import QtQuick.Shapes 1.13
import QtGraphicalEffects 1.13
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
Loader {
id: chatReply
property StatusMessageDetails replyDetails
property string audioMessageInfoText: ""
signal replyProfileClicked()
active: visible
sourceComponent: RowLayout {
id: replyLayout
spacing: 8
Shape {
id: replyCorner
Layout.alignment: Qt.AlignTop
Layout.leftMargin: 35
Layout.topMargin: profileImage.height/2
Layout.preferredWidth: 20
Layout.preferredHeight: messageLayout.height - replyCorner.Layout.topMargin
asynchronous: true
antialiasing: true
ShapePath {
strokeColor: Qt.hsla(Theme.palette.baseColor1.hslHue, Theme.palette.baseColor1.hslSaturation, Theme.palette.baseColor1.hslLightness, 0.4)
strokeWidth: 3
fillColor: "transparent"
capStyle: ShapePath.RoundCap
joinStyle: ShapePath.RoundJoin
startX: 20
startY: 0
PathLine { x: 10; y: 0 }
PathArc {
x: 0; y: 10
radiusX: 13
radiusY: 13
direction: PathArc.Counterclockwise
}
PathLine { x: 0; y: messageLayout.height}
}
}
ColumnLayout {
id: messageLayout
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
Layout.topMargin: 4
RowLayout {
StatusSmartIdenticon {
id: profileImage
Layout.alignment: Qt.AlignTop
image: replyDetails.profileImage
name: replyDetails.displayName
MouseArea {
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
onClicked: replyProfileClicked()
}
}
TextEdit {
Layout.alignment: Qt.AlignVCenter
color: Theme.palette.baseColor1
selectionColor: Theme.palette.primaryColor3
selectedTextColor: Theme.palette.directColor1
font.pixelSize: 13
font.weight: Font.Medium
selectByMouse: true
readOnly: true
text: replyDetails.displayName
}
}
StatusTextMessage {
Layout.fillWidth: true
textField.text: replyDetails.messageText
textField.font.pixelSize: 13
textField.color: Theme.palette.baseColor1
textField.height: 18
clip: true
visible: !!replyDetails.messageText
}
StatusImageMessage {
Layout.fillWidth: true
Layout.preferredHeight: imageAlias.paintedHeight
imageWidth: 56
source: replyDetails.contentType === StatusMessage.ContentType.Image ? replyDetails.messageContent : ""
visible: replyDetails.contentType === StatusMessage.ContentType.Image
shapeType: StatusImageMessage.ShapeType.ROUNDED
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: 48
Layout.alignment: Qt.AlignLeft
visible: replyDetails.contentType === StatusMessage.ContentType.Sticker
StatusSticker {
image.width: 48
image.height: 48
image.source: replyDetails.messageContent
}
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: 22
visible: replyDetails.contentType === StatusMessage.ContentType.Audio
StatusAudioMessage {
id: audioMessage
anchors.left: parent.left
width: 125
height: 22
isPreview: true
audioSource: replyDetails.messageContent
audioMessageInfoText: chatReply.audioMessageInfoText
}
}
}
}
}
@@ -1,46 +0,0 @@
import QtQuick 2.13
import QtQuick.Layouts 1.14
import QtGraphicalEffects 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Loader {
property string pinnedMsgInfoText: ""
property string pinnedBy: ""
active: visible
sourceComponent: Rectangle {
height: 24
width: layout.width + 16
color: Theme.palette.pinColor2
radius: 12
RowLayout {
id: layout
anchors.centerIn: parent
StatusIcon {
Layout.alignment: Qt.AlignVCenter
Layout.preferredWidth: 16
Layout.preferredHeight: 16
color: Theme.palette.pinColor1
icon: "tiny/pin"
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
Layout.leftMargin: -4
color: Theme.palette.directColor1
font.pixelSize: 13
text: pinnedMsgInfoText
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
Layout.leftMargin: -4
color: Theme.palette.directColor1
font.pixelSize: 13
font.weight: Font.Medium
text: pinnedBy
}
}
}
}
@@ -1,125 +0,0 @@
import QtQuick 2.3
import QtGraphicalEffects 1.13
import StatusQ.Components 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Loader {
id: statusSticker
property bool noHover: false
property bool noMouseArea: false
property StatusImageSettings image: StatusImageSettings {
width: 140
height: 140
}
signal loaded()
signal clicked()
active: visible
sourceComponent: Rectangle {
id: root
color: Theme.palette.baseColor2
radius: 16
width: image.width
height: image.height
function reload() {
// From the documentation (https://doc.qt.io/qt-5/qml-qtquick-image.html#sourceSize-prop)
// Note: Changing this property dynamically causes the image source to
// be reloaded, potentially even from the network, if it is not in the
// disk cache.
const oldSource = sticker.source
sticker.cache = false
sticker.sourceSize.width += 1
sticker.sourceSize.width -= 1
sticker.cache = true
}
Loader {
id: loader
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
}
Image {
id: sticker
anchors.fill: parent
horizontalAlignment: Image.AlignHCenter
verticalAlignment: Image.AlignVCenter
cache: true
source: image.source
onStatusChanged: {
if (status === Image.Ready) {
statusSticker.loaded()
}
}
MouseArea {
enabled: !noMouseArea && (sticker.status === Image.Ready)
cursorShape: noHover ? Qt.ArrowCursor : Qt.PointingHandCursor
anchors.fill: parent
onClicked: statusSticker.clicked()
}
}
Component {
id: loadingIndicator
StatusLoadingIndicator {
width: 24
height: 24
color: Theme.palette.baseColor1
}
}
Component {
id: reload
StatusIcon {
icon: "refresh"
color: Theme.palette.directColor1
mipmap: false
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: root.reload()
}
}
}
states: [
State {
name: "loading"
when: sticker.status === Image.Loading
PropertyChanges {
target: loader
sourceComponent: loadingIndicator
}
},
State {
name: "error"
when: sticker.status === Image.Error
PropertyChanges {
target: loader
sourceComponent: reload
}
},
State {
name: "ready"
when: sticker.status === Image.Ready
PropertyChanges {
target: root
color: "transparent"
}
PropertyChanges {
target: loader
sourceComponent: undefined
}
}
]
}
}
@@ -1,87 +0,0 @@
import QtQuick 2.13
import QtGraphicalEffects 1.0
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
Item {
id: textMessage
property int contentType: 0
property alias textField: chatText
signal linkActivated(url link)
implicitHeight: showMoreLoader.active ? childrenRect.height : chatText.height
QtObject {
id: _internal
property bool readMore: false
property bool veryLongChatText: chatText.length > 1000
}
TextEdit {
id: chatText
visible: !showMoreLoader.active || _internal.readMore
selectedTextColor: Theme.palette.directColor1
selectionColor: Theme.palette.primaryColor3
color: Theme.palette.directColor1
font.family: Theme.palette.baseFont.name
font.pixelSize: 15
textFormat: Text.RichText
wrapMode: Text.Wrap
readOnly: true
selectByMouse: true
height: _internal.veryLongChatText && !_internal.readMore ? Math.min(implicitHeight, 200) : implicitHeight
width: parent.width
clip: height < implicitHeight
onLinkActivated: textMessage.linkActivated(link)
onLinkHovered: {
cursorShape: Qt.PointingHandCursor
}
}
Loader {
id: mask
anchors.fill: chatText
active: showMoreLoader.active
visible: false
sourceComponent: LinearGradient {
start: Qt.point(0, 0)
end: Qt.point(0, chatText.height)
gradient: Gradient {
GradientStop { position: 0.0; color: "white" }
GradientStop { position: 0.85; color: "white" }
GradientStop { position: 1; color: "transparent" }
}
}
}
Loader {
id: opMask
active: showMoreLoader.active && !_internal.readMore
anchors.fill: chatText
sourceComponent: OpacityMask {
source: chatText
maskSource: mask
}
}
Loader {
id: showMoreLoader
active: _internal.veryLongChatText
anchors.top: chatText.bottom
anchors.topMargin: -10
anchors.horizontalCenter: parent.horizontalCenter
sourceComponent: StatusRoundButton {
implicitWidth: 24
implicitHeight: 24
type: StatusRoundButton.Type.Secondary
icon.name: _internal.readMore ? "chevron-up": "chevron-down"
onClicked: {
_internal.readMore = !_internal.readMore
}
}
}
}
@@ -1,24 +0,0 @@
import QtQuick 2.13
import QtQuick.Layouts 1.14
import StatusQ.Controls 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
StatusBaseText {
id: timestampLabe;
property alias tooltip: tooltip
Layout.alignment: Qt.AlignVCenter
color: Theme.palette.baseColor1
font.pixelSize: 10
visible: !!text
StatusToolTip {
id: tooltip
visible: hhandler.hovered && !!text
maxWidth: 350
}
HoverHandler {
id: hhandler
}
}
-8
View File
@@ -1,6 +1,5 @@
module StatusQ.Components
StatusAddress 0.1 StatusAddress.qml
StatusBadge 0.1 StatusBadge.qml
StatusChatInfoToolBar 0.1 StatusChatInfoToolBar.qml
StatusChatList 0.1 StatusChatList.qml
@@ -15,7 +14,6 @@ StatusLetterIdenticon 0.1 StatusLetterIdenticon.qml
StatusListItem 0.1 StatusListItem.qml
StatusListSectionHeadline 0.1 StatusListSectionHeadline.qml
StatusLoadingIndicator 0.1 StatusLoadingIndicator.qml
StatusMemberListItem 0.1 StatusMemberListItem.qml
StatusNavigationListItem 0.1 StatusNavigationListItem.qml
StatusNavigationPanelHeadline 0.1 StatusNavigationPanelHeadline.qml
StatusRoundIcon 0.1 StatusRoundIcon.qml
@@ -23,9 +21,3 @@ StatusRoundedImage 0.1 StatusRoundedImage.qml
StatusMacWindowButtons 0.1 StatusMacWindowButtons.qml
StatusListItemBadge 0.1 StatusListItemBadge.qml
StatusExpandableItem 0.1 StatusExpandableItem.qml
StatusSmartIdenticon 0.1 StatusSmartIdenticon.qml
StatusMessage 0.1 StatusMessage.qml
StatusMessageDetails 0.1 StatusMessageDetails.qml
StatusTagSelector 0.1 StatusTagSelector.qml
StatusToastMessage 0.1 StatusToastMessage.qml
StatusWizardStepper 0.1 StatusWizardStepper.qml
@@ -1,277 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtQml.Models 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Controls 0.1
Item {
id: root
property string label: "Choose account"
property bool showAccountDetails: !!selectedAccount
property var accounts
property var selectedAccount
property string currency: "usd"
property alias selectField: select
implicitWidth: 448
height: select.height +
(selectedAccountDetails.visible ? selectedAccountDetails.height + selectedAccountDetails.anchors.topMargin : 0)
// set to asset symbol to display asset's balance top right
// NOTE: if this asset is not selected as a wallet token in the UI, then
// nothing will be displayed
property string showBalanceForAssetSymbol: ""
property var assetFound
property double minRequiredAssetBalance: 0
property int dropdownWidth: width
property alias dropdownAlignment: select.menuAlignment
property bool isValid: true
property bool readOnly: false
property var assetBalanceTextFn: function (foundValue) {
return "Balance: " + (parseFloat(foundValue) === 0.0 ? "0" : Utils.stripTrailingZeros(foundValue))
}
readonly property string watchWalletType: "watch"
enum Type {
Address,
Contact,
Account
}
function validate() {
if (showBalanceForAssetSymbol == "" || minRequiredAssetBalance == 0 || !assetFound) {
return root.isValid
}
root.isValid = assetFound.balance >= minRequiredAssetBalance
return root.isValid
}
onSelectedAccountChanged: {
if (!selectedAccount) {
return
}
if (selectedAccount.color) {
selectedIconImg.color = Utils.getThemeAccountColor(selectedAccount.color, Theme.palette.accountColors) || Theme.palette.accountColors[0]
}
if (selectedAccount.name) {
selectedTextField.text = selectedAccount.name
}
if (selectedAccount.address) {
textSelectedAddress.text = selectedAccount.address + " •"
}
if (selectedAccount.currencyBalance) {
textSelectedAddressFiatBalance.text = selectedAccount.currencyBalance + " " + currency.toUpperCase()
}
if (selectedAccount.assets && showBalanceForAssetSymbol) {
assetFound = Utils.findAssetBySymbol(selectedAccount.assets, showBalanceForAssetSymbol)
if (!assetFound) {
console.warn("Cannot find asset '", showBalanceForAssetSymbol, "'. Ensure this asset has been added to the token list.")
}
}
if (!selectedAccount.type) {
selectedAccount.type = StatusAccountSelector.Type.Account
}
validate()
}
onAssetFoundChanged: {
if (!assetFound) {
return
}
txtAssetBalance.text = root.assetBalanceTextFn(assetFound.balance)
txtAssetSymbol.text = " " + assetFound.symbol
}
StatusBaseText {
id: txtAssetBalance
visible: root.assetFound !== undefined
anchors.bottom: select.top
anchors.bottomMargin: -18
anchors.right: txtAssetSymbol.left
anchors.left: select.left
anchors.leftMargin: select.width / 2.5
color: !root.isValid ? Theme.palette.dangerColor1 : Theme.palette.baseColor1
elide: Text.ElideRight
font.pixelSize: 13
horizontalAlignment: Text.AlignRight
height: 18
StatusToolTip {
enabled: txtAssetBalance.truncated
id: assetTooltip
text: txtAssetBalance.text
}
MouseArea {
enabled: txtAssetBalance.truncated
anchors.fill: parent
hoverEnabled: enabled
onEntered: assetTooltip.visible = true
onExited: assetTooltip.visible = false
}
}
StatusBaseText {
id: txtAssetSymbol
visible: txtAssetBalance.visible
anchors.top: txtAssetBalance.top
anchors.right: parent.right
color: txtAssetBalance.color
font.pixelSize: 13
height: txtAssetBalance.height
}
StatusSelect {
id: select
label: root.label
model: root.accounts
width: parent.width
menuAlignment: StatusSelect.MenuAlignment.Left
selectMenu.delegate: menuItem
selectMenu.width: dropdownWidth
selectedItemComponent: Item {
anchors.fill: parent
StatusIcon {
id: selectedIconImg
anchors.left: parent.left
anchors.leftMargin: 16
anchors.verticalCenter: parent.verticalCenter
width: 20
height: 20
icon: "filled-account"
}
StatusBaseText {
id: selectedTextField
elide: Text.ElideRight
anchors.left: selectedIconImg.right
anchors.leftMargin: 8
anchors.right: parent.right
anchors.rightMargin: select.selectedItemRightMargin
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 15
verticalAlignment: Text.AlignVCenter
height: 22
color: Theme.palette.directColor1
}
}
}
Row {
id: selectedAccountDetails
visible: root.showAccountDetails
anchors.top: select.bottom
anchors.topMargin: 8
anchors.left: parent.left
anchors.leftMargin: 2
StatusBaseText {
id: textSelectedAddress
font.pixelSize: 12
elide: Text.ElideMiddle
width: 90
color: Theme.palette.baseColor1
}
StatusBaseText {
id: textSelectedAddressFiatBalance
font.pixelSize: 12
color: Theme.palette.baseColor1
}
}
Component {
id: menuItem
MenuItem {
id: itemContainer
visible: walletType !== root.watchWalletType
property bool isFirstItem: index === 0
property bool isLastItem: index === accounts.rowCount() - 1
Component.onCompleted: {
if (!root.selectedAccount && isFirstItem) {
root.selectedAccount = { address, name, color: model.color, assets, currencyBalance }
}
}
height: walletType === root.watchWalletType ? 0 : (accountName.height + 14 + accountAddress.height + 14)
StatusIcon {
id: iconImg
anchors.left: parent.left
anchors.leftMargin: 16
anchors.verticalCenter: parent.verticalCenter
width: 20
height: 20
icon: "filled-account"
color: Utils.getThemeAccountColor(model.color, Theme.palette.accountColors) || Theme.palette.accountColors[0]
}
Column {
id: column
anchors.left: iconImg.right
anchors.leftMargin: 14
anchors.right: txtFiatBalance.left
anchors.rightMargin: 8
anchors.verticalCenter: parent.verticalCenter
StatusBaseText {
id: accountName
text: model.name
elide: Text.ElideRight
font.pixelSize: 15
anchors.left: parent.left
anchors.right: parent.right
height: 22
color: Theme.palette.directColor1
}
StatusBaseText {
id: accountAddress
text: address
elide: Text.ElideMiddle
width: 80
color: Theme.palette.baseColor1
font.pixelSize: 12
height: 16
}
}
StatusBaseText {
id: txtFiatBalance
anchors.right: fiatCurrencySymbol.left
anchors.rightMargin: 4
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 15
height: 22
text: currencyBalance
color: Theme.palette.directColor1
}
StatusBaseText {
id: fiatCurrencySymbol
anchors.right: parent.right
anchors.rightMargin: 16
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 15
height: 22
color: Theme.palette.baseColor1
text: root.currency.toUpperCase()
}
background: Rectangle {
color: itemContainer.highlighted ? Theme.palette.statusSelect.menuItemHoverBackgroundColor : Theme.palette.statusSelect.menuItemBackgroundColor
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: itemContainer
onClicked: {
root.selectedAccount = { address, name, color: model.color, assets, currencyBalance }
select.selectMenu.close()
}
}
}
}
}
@@ -1,146 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
Item {
id: root
property var assets
property var selectedAsset
property string defaultToken: ""
property var tokenAssetSourceFn: function (symbol) {
return ""
}
// Define this in the usage to get balance in currency selected by user
property var getCurrencyBalanceString: function (currencyBalance) { return "" }
implicitWidth: 86
implicitHeight: 32
function resetInternal() {
assets = null
selectedAsset = null
}
onSelectedAssetChanged: {
if (selectedAsset && selectedAsset.symbol) {
iconImg.image.source = tokenAssetSourceFn(selectedAsset.symbol.toUpperCase())
selectedTextField.text = selectedAsset.symbol.toUpperCase()
}
}
StatusSelect {
id: select
width: parent.width
bgColor: "transparent"
bgColorHover: Theme.palette.directColor8
model: root.assets
caretRightMargin: 0
select.radius: 6
select.height: root.height
selectMenu.width: 342
selectedItemComponent: Item {
anchors.fill: parent
StatusRoundedImage {
id: iconImg
anchors.left: parent.left
anchors.leftMargin: 4
width: 24
height: 24
anchors.verticalCenter: parent.verticalCenter
image.onStatusChanged: {
if (iconImg.image.status === Image.Error) {
iconImg.image.source = defaultToken
}
}
}
StatusBaseText {
id: selectedTextField
anchors.left: iconImg.right
anchors.leftMargin: 4
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: 15
height: 22
verticalAlignment: Text.AlignVCenter
color: Theme.palette.directColor1
}
}
selectMenu.delegate: menuItem
}
Component {
id: menuItem
MenuItem {
id: itemContainer
property bool isFirstItem: index === 0
property bool isLastItem: index === assets.rowCount() - 1
width: parent.width
height: 72
StatusRoundedImage {
id: iconImg
anchors.left: parent.left
anchors.leftMargin: 16
anchors.verticalCenter: parent.verticalCenter
image.source: root.tokenAssetSourceFn(symbol.toUpperCase())
image.onStatusChanged: {
if (iconImg.image.status === Image.Error) {
iconImg.image.source = defaultToken
}
}
}
Column {
anchors.left: iconImg.right
anchors.leftMargin: 12
anchors.verticalCenter: parent.verticalCenter
StatusBaseText {
text: symbol.toUpperCase()
font.pixelSize: 15
color: Theme.palette.directColor1
}
StatusBaseText {
text: name
color: Theme.palette.baseColor1
font.pixelSize: 15
}
}
Column {
anchors.right: parent.right
anchors.rightMargin: 16
anchors.verticalCenter: parent.verticalCenter
StatusBaseText {
font.pixelSize: 15
text: parseFloat(balance).toFixed(4) + " " + symbol
}
StatusBaseText {
font.pixelSize: 15
anchors.right: parent.right
text: getCurrencyBalanceString(currencyBalance)
color: Theme.palette.baseColor1
}
}
background: Rectangle {
color: itemContainer.highlighted ? Theme.palette.statusSelect.menuItemHoverBackgroundColor : Theme.palette.statusSelect.menuItemBackgroundColor
}
Component.onCompleted: {
if(index === 0 ) {
selectedAsset = { name: name, symbol: symbol, address: address, balance: balance, currencyBalance: currencyBalance}
}
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: itemContainer
onClicked: {
selectedAsset = {name: name, symbol: symbol, address: address, balance: balance, currencyBalance: currencyBalance}
select.selectMenu.close()
}
}
}
}
}
-89
View File
@@ -1,89 +0,0 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Column {
id: statusBanner
width: parent.width
property string statusText
property int type: StatusBanner.Type.Info
property int textPixels: 15
property int statusBannerHeight: 38
// "private" properties
QtObject {
id: d
property color backgroundColor
property color bordersColor
property color fontColor
}
enum Type {
Info, // 0
Danger, // 1
Success, // 2
Warning // 3
}
// Component definition
Rectangle {
id: topDiv
color: d.bordersColor
height: 1
width: parent.width
}
Rectangle {
id: box
width: parent.width
height: statusBanner.statusBannerHeight
color: d.backgroundColor
StatusBaseText {
id: statusTxt
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: statusBanner.textPixels
text: statusBanner.statusText
color: d.fontColor
}
}
Rectangle {
id: bottomDiv
color: d.bordersColor
height: 1
width: parent.width
}
// Behavior
states: [
State {
when: statusBanner.type === StatusBanner.Type.Info
PropertyChanges { target: d; backgroundColor: Theme.palette.primaryColor3}
PropertyChanges { target: d; bordersColor: Theme.palette.primaryColor2}
PropertyChanges { target: d; fontColor: Theme.palette.primaryColor1}
},
State {
when: statusBanner.type === StatusBanner.Type.Danger
PropertyChanges { target: d; backgroundColor: Theme.palette.dangerColor3}
PropertyChanges { target: d; bordersColor: Theme.palette.dangerColor2}
PropertyChanges { target: d; fontColor: Theme.palette.dangerColor1}
},
State {
when: statusBanner.type === StatusBanner.Type.Success
PropertyChanges { target: d; backgroundColor: Theme.palette.successColor2}
PropertyChanges { target: d; bordersColor: Theme.palette.successColor2}
PropertyChanges { target: d; fontColor: Theme.palette.successColor1}
},
State {
when: statusBanner.type === StatusBanner.Type.Warning
PropertyChanges { target: d; backgroundColor: Theme.palette.pinColor3}
PropertyChanges { target: d; bordersColor: Theme.palette.pinColor2}
PropertyChanges { target: d; fontColor: Theme.palette.pinColor1}
}
]
}
+4 -30
View File
@@ -7,7 +7,6 @@ Rectangle {
id: statusBaseButton
enum Size {
Tiny,
Small,
Large
}
@@ -34,32 +33,8 @@ Rectangle {
property real defaultLeftPadding: size === StatusBaseButton.Size.Large ? 24 : 12
property real defaultRightPadding: size === StatusBaseButton.Size.Large ? 24 : 12
property real defaultTopPadding: {
switch (size) {
case StatusBaseButton.Size.Tiny:
return 5
case StatusBaseButton.Size.Small:
return 10
break;
case StatusBaseButton.Size.Large:
default:
return 11
break;
}
}
property real defaultBottomPadding: {
switch (size) {
case StatusBaseButton.Size.Tiny:
return 5
case StatusBaseButton.Size.Small:
return 10
break;
case StatusBaseButton.Size.Large:
default:
return 11
break;
}
}
property real defaultTopPadding: size === StatusBaseButton.Size.Large ? 11 : 10
property real defaultBottomPadding: size === StatusBaseButton.Size.Large ? 11 : 10
property real leftPadding: defaultLeftPadding
@@ -79,7 +54,6 @@ Rectangle {
signal clicked(var mouse)
signal pressAndHold(var mouse)
property bool highlighted: false
/// Implementation
@@ -87,11 +61,11 @@ Rectangle {
implicitWidth: sensor.width
implicitHeight: sensor.height
radius: size !== StatusBaseButton.Size.Tiny ? 8 : 6
radius: 8
color: {
if (statusBaseButton.enabled) {
return sensor.containsMouse || highlighted ? hoverColor
return sensor.containsMouse ? hoverColor
: normalColor
} else {
return disaledColor
+2 -1
View File
@@ -142,11 +142,12 @@ Item {
return clearable ? clearButtonLoader.width + 12 :
(statusIcon.visible && !leftIcon) || !!statusBaseInput.component ? 8 : 0
}
anchors.topMargin: statusBaseInput.topPadding
anchors.bottomMargin: statusBaseInput.bottomPadding
contentWidth: edit.paintedWidth
contentHeight: edit.paintedHeight
boundsBehavior: Flickable.StopAtBounds
QC.ScrollBar.vertical: QC.ScrollBar { interactive: multiline; enabled: multiline }
clip: true
function ensureVisible(r) {
if (contentX >= r.x)
contentX = r.x;
@@ -1,71 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
Rectangle {
id: root
implicitWidth: 168
implicitHeight: 95
property string text: ""
property bool highlighted: false
property bool enabled: true
signal clicked(var mouse)
property StatusIconSettings icon: StatusIconSettings {
width: 24
height: 24
background: StatusIconBackgroundSettings {}
}
color: {
let actualColor = Qt.darker(root.icon.color, 1)
actualColor.a = sensor.containsMouse && enabled ? 0.3 : 0.2
return actualColor
}
radius: 16
MouseArea {
id: sensor
cursorShape: root.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
anchors.fill: parent
hoverEnabled: true
onClicked: function (mouse) {
root.clicked(mouse)
}
StatusRoundIcon {
icon.name: root.icon.name
icon.width: root.icon.width
icon.height: root.icon.height
icon.rotation: root.icon.rotation
icon.color: Theme.palette.white
icon.background.width: 40
icon.background.height: 40
icon.background.color: root.icon.color
anchors.top: parent.top
anchors.topMargin: 8
anchors.left: parent.left
anchors.leftMargin: 8
}
StatusBaseText {
text: root.text
anchors.left: parent.left
anchors.leftMargin: 8
anchors.bottom: parent.bottom
anchors.bottomMargin: 8
font.pixelSize: 13
font.weight: Font.Medium
color: Theme.palette.white
}
}
}
+46 -18
View File
@@ -18,15 +18,8 @@ Rectangle {
property string subTitle: ""
property bool muted: false
property int pinnedMessagesCount: 0
property StatusImageSettings image: StatusImageSettings {
width: 36
height: 36
}
property StatusIconSettings icon: StatusIconSettings {
width: 36
height: 36
letterSize: 20
}
property StatusImageSettings image: StatusImageSettings {}
property StatusIconSettings icon: StatusIconSettings {}
property int type: StatusChatInfoButton.Type.PublicChat
property alias tooltip: statusToolTip
property alias sensor: sensor
@@ -34,7 +27,6 @@ Rectangle {
signal clicked(var mouse)
signal pinnedMessagesCountClicked(var mouse)
signal unmute()
signal linkActivated(string link)
enum Type {
Unknown0, // 0
@@ -57,14 +49,51 @@ Rectangle {
onClicked: statusChatInfoButton.clicked(mouse)
StatusSmartIdenticon {
Loader {
id: identicon
anchors.left: parent.left
anchors.leftMargin: 4
anchors.verticalCenter: parent.verticalCenter
image: statusChatInfoButton.image
icon: statusChatInfoButton.icon
name: statusChatInfoButton.title
sourceComponent: !!statusChatInfoButton.image.source.toString() ?
statusRoundImageComponent :
statusLetterIdenticonComponent
}
Component {
id: statusRoundImageComponent
Item {
width: 36
height: 36
StatusRoundedImage {
id: statusRoundImage
width: parent.width
height: parent.height
image.source: statusChatInfoButton.image.source
showLoadingIndicator: true
border.width: statusChatInfoButton.image.isIdenticon ? 1 : 0
border.color: Theme.palette.directColor7
}
Loader {
sourceComponent: statusLetterIdenticonComponent
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
active: statusRoundImage.image.status === Image.Error
}
}
}
Component {
id: statusLetterIdenticonComponent
StatusLetterIdenticon {
width: 36
height: 36
name: statusChatInfoButton.title
color: statusChatInfoButton.icon.color
}
}
Item {
@@ -132,7 +161,6 @@ Rectangle {
}
StatusIcon {
objectName: "mutedIcon"
id: mutedIcon
anchors.left: chatName.right
anchors.leftMargin: 4
@@ -178,14 +206,15 @@ Rectangle {
+ divider.width + divider.anchors.leftMargin
: 0
StatusSelectableText {
StatusBaseText {
id: chatType
text: statusChatInfoButton.subTitle
color: Theme.palette.baseColor1
font.pixelSize: 12
elide: Text.ElideRight
width: Math.min(parent.width - (pinIcon.visible ? divider.width + divider.anchors.leftMargin + pinIcon.width + pinIcon.anchors.leftMargin : 0),
implicitWidth)
onLinkActivated: statusChatInfoButton.linkActivated(link)
}
Rectangle {
@@ -224,7 +253,6 @@ Rectangle {
color: pinCountSensor.containsMouse ? Theme.palette.directColor1 : Theme.palette.baseColor1
MouseArea {
objectName: "pinMessagesCounterSensor"
id: pinCountSensor
anchors.fill: parent
hoverEnabled: true
@@ -1,37 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import StatusQ.Controls 0.1
Item {
id: root
property string selectedColor
property string label: "Color"
property var model
height: accountColorInput.height
implicitWidth: 448
StatusSelect {
id: accountColorInput
bgColor: selectedColor
label: root.label
model: root.model
selectMenu.delegate: Component {
MenuItem {
property bool isFirstItem: index === 0
property bool isLastItem: index === root.model.length - 1
height: 52
width: parent.width
padding: 10
onTriggered: function () {
const selectedColor = root.model[index]
root.selectedColor = selectedColor
}
background: Rectangle {
color: root.model[index] || "transparent"
}
}
}
}
}
+3 -20
View File
@@ -18,19 +18,14 @@ Rectangle {
return Theme.palette.directColor1;
case StatusFlatRoundButton.Type.Primary:
return Theme.palette.primaryColor1;
case StatusFlatRoundButton.Type.Tertiary:
return hovered ? Theme.palette.primaryColor1: Theme.palette.baseColor1;
case StatusFlatRoundButton.Type.Quaternary:
return hovered ? Theme.palette.primaryColor1: Theme.palette.directColor1;
}
}
disabledColor: {
property color disabledColor: {
switch(statusFlatRoundButton.type) {
case StatusFlatRoundButton.Type.Secondary:
return Theme.palette.baseColor1;
case StatusFlatRoundButton.Type.Primary:
case StatusFlatRoundButton.Type.Tertiary:
case StatusFlatRoundButton.Type.Quaternary:
return Theme.palette.baseColor1;
}
}
@@ -40,7 +35,6 @@ Rectangle {
property alias hovered: sensor.containsMouse
property alias tooltip: statusToolTip
property alias backgroundHoverColor: backgroundSettings.hoverColor
property bool highlighted: false
@@ -53,9 +47,7 @@ Rectangle {
enum Type {
Primary,
Secondary,
Tertiary,
Quaternary
Secondary
}
/// Implementation
@@ -67,8 +59,6 @@ Rectangle {
switch(statusFlatRoundButton.type) {
case StatusFlatRoundButton.Type.Primary:
case StatusFlatRoundButton.Type.Secondary:
case StatusFlatRoundButton.Type.Tertiary:
case StatusFlatRoundButton.Type.Quaternary:
return "transparent";
}
}
@@ -78,8 +68,6 @@ Rectangle {
case StatusFlatRoundButton.Type.Primary:
return Theme.palette.primaryColor3;
case StatusFlatRoundButton.Type.Secondary:
case StatusFlatRoundButton.Type.Tertiary:
case StatusFlatRoundButton.Type.Quaternary:
return Theme.palette.baseColor2;
}
}
@@ -88,8 +76,6 @@ Rectangle {
switch(statusFlatRoundButton.type) {
case StatusFlatRoundButton.Type.Primary:
case StatusFlatRoundButton.Type.Secondary:
case StatusFlatRoundButton.Type.Tertiary:
case StatusFlatRoundButton.Type.Quaternary:
return "transparent";
}
}
@@ -99,8 +85,6 @@ Rectangle {
case StatusFlatRoundButton.Type.Primary:
return Theme.palette.primaryColor3;
case StatusFlatRoundButton.Type.Secondary:
case StatusFlatRoundButton.Type.Tertiary:
case StatusFlatRoundButton.Type.Quaternary:
return Theme.palette.baseColor4;
}
}
@@ -136,7 +120,6 @@ Rectangle {
visible: !loading
icon: statusFlatRoundButton.icon.name
source: statusFlatRoundButton.icon.source
rotation: statusFlatRoundButton.icon.rotation
width: statusFlatRoundButton.icon.width
+48 -12
View File
@@ -20,20 +20,56 @@ TabButton {
contentItem: Item {
anchors.fill: parent
StatusSmartIdenticon {
id: identicon
Loader {
active: true
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
image.source: statusIconTabButton.icon.source
image.width: 28
image.height: 28
icon.height: statusIconTabButton.icon.height
icon.width: statusIconTabButton.icon.width
icon.name: statusIconTabButton.icon.name
icon.color: (statusIconTabButton.hovered || highlighted || statusIconTabButton.checked) ? Theme.palette.primaryColor1 : statusIconTabButton.icon.color
icon.isLetterIdenticon: statusIconTabButton.name !== "" && !statusIconTabButton.icon.source.toString()
icon.letterSize: 15
name: statusIconTabButton.name
sourceComponent: statusIconTabButton.name !== "" && !icon.source.toString() ? letterIdenticon :
!!icon.source.toString() ? imageIcon : defaultIcon
}
Component {
id: defaultIcon
StatusIcon {
icon: statusIconTabButton.icon.name
height: statusIconTabButton.icon.height
width: statusIconTabButton.icon.width
color: (statusIconTabButton.hovered || highlighted || statusIconTabButton.checked) ? Theme.palette.primaryColor1 : statusIconTabButton.icon.color
}
}
Component {
id: imageIcon
Item {
width: 28
height: 28
StatusRoundedImage {
id: statusRoundImage
showLoadingIndicator: true
width: parent.width
height: parent.height
image.source: icon.source
}
Loader {
sourceComponent:letterIdenticon
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
active: statusRoundImage.image.status === Image.Error
}
}
}
Component {
id: letterIdenticon
StatusLetterIdenticon {
width: 26
height: 26
letterSize: 15
name: statusIconTabButton.name
color: (statusIconTabButton.hovered || highlighted || statusIconTabButton.checked) ? Theme.palette.primaryColor1 : statusIconTabButton.icon.color
}
}
}
-5
View File
@@ -72,11 +72,6 @@ Item {
if (!errors) {
errors = {}
}
if (typeof result === "boolean") {
result = {
valid: result
}
}
result.errorMessage = validator.errorMessage
errors[validator.name] = result
statusBaseInput.valid = statusBaseInput.valid && false
@@ -1,54 +0,0 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import StatusQ.Core.Theme 0.1
import StatusQ.Core 0.1
StatusProgressBar {
id: control
property var strength
property string labelVeryWeak: "Very weak"
property string labelWeak: "Weak"
property string labelSoso: "So-so"
property string labelGood: "Good"
property string labelGreat: "Great"
enum Strength {
VeryWeak, // 0
Weak, // 1
SoSo, // 2
Good, // 3
Great // 4
}
// Behavior:
states: [
// Strength states definition:
State {
when: control.strength === StatusPasswordStrengthIndicator.Strength.VeryWeak
PropertyChanges { target: control; fillColor : Theme.palette.dangerColor1}
PropertyChanges { target: control; text: labelVeryWeak}
},
State {
when: control.strength === StatusPasswordStrengthIndicator.Strength.Weak
PropertyChanges { target: control; fillColor : Theme.palette.pinColor1}
PropertyChanges { target: control; text: labelWeak}
},
State {
when: control.strength === StatusPasswordStrengthIndicator.Strength.SoSo
PropertyChanges { target: control; fillColor : Theme.palette.miscColor7}
PropertyChanges { target: control; text: labelSoso}
},
State {
when: control.strength === StatusPasswordStrengthIndicator.Strength.Good
PropertyChanges { target: control; fillColor : Theme.palette.miscColor12}
PropertyChanges { target: control; text: labelGood}
},
State {
when: control.strength === StatusPasswordStrengthIndicator.Strength.Great
PropertyChanges { target: control; fillColor : Theme.palette.successColor1}
PropertyChanges { target: control; text: labelGreat}
}
]
}
@@ -1,44 +0,0 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import StatusQ.Core.Theme 0.1
import StatusQ.Core 0.1
ProgressBar {
id: control
property string text
property color fillColor
property color backgroundColor: Theme.palette.directColor8
property color backgroundBorderColor: "transparent"
width: 416
height: 16
clip: true
background: Rectangle {
implicitWidth: parent.width
implicitHeight: parent.height
color: control.backgroundColor
border.color: control.backgroundBorderColor
radius: 5
}
contentItem: Item {
implicitHeight: parent.height
Rectangle {
id: bar
width: control.visualPosition * parent.width
height: parent.height
color: control.fillColor
radius: 5
StatusBaseText {
anchors.centerIn: parent
text: control.text
font.pixelSize: 12
color: Theme.palette.indirectColor1
}
}
}
}
+2 -2
View File
@@ -21,7 +21,7 @@ Rectangle {
}
}
disabledColor: {
property color disabledColor: {
switch(statusRoundButton.type) {
case StatusRoundButton.Type.Primary:
return Theme.palette.baseColor1;
@@ -77,7 +77,7 @@ Rectangle {
property color disabledColor: {
switch(statusRoundButton.type) {
case StatusRoundButton.Type.Primary:
return Theme.palette.baseColor2;
return Theme.palette.indirectColor1;
case StatusRoundButton.Type.Secondary:
return Theme.palette.baseColor1;
}
-175
View File
@@ -1,175 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Popups 0.1
Item {
enum MenuAlignment {
Left,
Right,
Center
}
property string label: ""
readonly property bool hasLabel: label !== ""
property color bgColor: Theme.palette.baseColor2
readonly property int labelMargin: 7
property var model
property alias selectMenu: selectMenu
property color bgColorHover: bgColor
property alias selectedItemComponent: selectedItemContainer.children
property int caretRightMargin: 16
property alias select: inputRectangle
property int menuAlignment: StatusSelect.MenuAlignment.Right
property Item zeroItemsView: Item {}
property string validationError: ""
property alias validationErrorAlignment: validationErrorText.horizontalAlignment
property int validationErrorTopMargin: 11
implicitWidth: 448
id: root
height: inputRectangle.height + (hasLabel ? inputLabel.height + labelMargin : 0) + (!!validationError ? (validationErrorText.height + validationErrorTopMargin) : 0)
StatusBaseText {
id: inputLabel
visible: hasLabel
text: root.label
anchors.left: parent.left
anchors.leftMargin: 0
anchors.top: parent.top
anchors.topMargin: 0
font.pixelSize: 15
color: root.enabled ? Theme.palette.directColor1 : Theme.palette.baseColor1
}
Rectangle {
property bool hovered: false
id: inputRectangle
height: 56
color: hovered ? bgColorHover : bgColor
radius: 8
anchors.top: root.hasLabel ? inputLabel.bottom : parent.top
anchors.topMargin: root.hasLabel ? root.labelMargin : 0
anchors.right: parent.right
anchors.left: parent.left
border.width: !!validationError ? 1 : 0
border.color: Theme.palette.dangerColor1
Item {
id: selectedItemContainer
anchors.fill: parent
}
StatusIcon {
id: caret
anchors.right: parent.right
anchors.rightMargin: caretRightMargin
anchors.verticalCenter: parent.verticalCenter
width: 24
height: 24
icon: "chevron-down"
color: Theme.palette.baseColor1
}
}
Rectangle {
width: selectMenu.width
height: selectMenu.height
x: selectMenu.x
y: selectMenu.y
visible: selectMenu.opened
color: Theme.palette.statusSelect.menuItemBackgroundColor
radius: 8
border.color: Theme.palette.baseColor2
layer.enabled: true
layer.effect: DropShadow {
verticalOffset: 3
radius: 8
samples: 15
fast: true
cached: true
color: Theme.palette.dropShadow
}
}
StatusPopupMenu {
id: selectMenu
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
width: parent.width
clip: true
Repeater {
id: menuItems
model: root.model
property int zeroItemsViewHeight
delegate: selectMenu.delegate
onItemAdded: {
root.zeroItemsView.visible = false
root.zeroItemsView.height = 0
}
onItemRemoved: {
if (count === 0) {
root.zeroItemsView.visible = true
root.zeroItemsView.height = zeroItemsViewHeight
}
}
Component.onCompleted: {
zeroItemsViewHeight = root.zeroItemsView.height
root.zeroItemsView.visible = count === 0
root.zeroItemsView.height = count !== 0 ? 0 : root.zeroItemsView.height
selectMenu.insertItem(0, root.zeroItemsView)
}
}
}
StatusBaseText {
id: validationErrorText
visible: !!validationError
text: validationError
anchors.top: inputRectangle.bottom
anchors.topMargin: validationErrorTopMargin
anchors.right: parent.right
anchors.left: parent.left
font.pixelSize: 12
height: visible ? implicitHeight : 0
color: Theme.palette.dangerColor1
horizontalAlignment: TextEdit.AlignRight
wrapMode: Text.WordWrap
}
MouseArea {
id: mouseArea
anchors.fill: inputRectangle
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onEntered: {
inputRectangle.hovered = true
}
onExited: {
inputRectangle.hovered = false
}
onClicked: {
if (selectMenu.opened) {
selectMenu.close()
} else {
const rightOffset = inputRectangle.width - selectMenu.width
let offset = rightOffset
switch (root.menuAlignment) {
case StatusSelect.MenuAlignment.Left:
offset = 0
break
case StatusSelect.MenuAlignment.Right:
offset = rightOffset
break
case StatusSelect.MenuAlignment.Center:
offset = rightOffset / 2
}
selectMenu.popup(inputRectangle.x + offset, inputRectangle.y + inputRectangle.height + 8)
}
}
}
}
@@ -1,105 +0,0 @@
import QtQuick 2.14
import QtQuick.Controls 2.14 as QC
import StatusQ.Controls 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Item {
id: statusSelectableText
property bool multiline: false
property string text: ""
property string hoveredLinkColor: Theme.palette.directColor1
property alias selectedText: edit.selectedText
property alias selectedTextColor: edit.selectedTextColor
property alias selectionStart: edit.selectionStart
property alias selectionEnd: edit.selectionEnd
property alias cursorPosition: edit.cursorPosition
property alias hoveredLink: edit.hoveredLink
property alias color: edit.color
property alias font: edit.font
property alias focussed: edit.activeFocus
property alias verticalAlignmet: edit.verticalAlignment
property alias horizontalAlignment: edit.horizontalAlignment
signal linkActivated(string link)
implicitWidth: multiline ? 0 : edit.implicitWidth
implicitHeight: edit.implicitHeight
clip:true
MouseArea {
id: sensor
enabled: !edit.activeFocus
hoverEnabled: true
anchors.fill: parent
cursorShape: Qt.IBeamCursor
onClicked: {
edit.forceActiveFocus()
}
onExited: {
flick.contentX = 0
flick.contentY = 0
}
Flickable {
id: flick
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
contentWidth: edit.paintedWidth
contentHeight: edit.paintedHeight
boundsBehavior: Flickable.StopAtBounds
QC.ScrollBar.vertical: QC.ScrollBar { interactive: multiline; enabled: multiline }
function ensureVisible(r) {
if (width-contentX >= r.x) {
contentX = 0;
}
else if (contentX+width <= r.x+r.width) {
contentX = r.x+r.width-width;
}
if (contentY >= r.y)
contentY = r.y;
else if (contentY+height <= r.y+r.height)
contentY = r.y+r.height-height;
}
TextEdit {
id: edit
width: flick.width
height: flick.height
verticalAlignment: Text.AlignVCenter
readOnly: true
selectByMouse: true
selectionColor: Theme.palette.primaryColor2
selectedTextColor: color
focus: true
font.pixelSize: 15
font.family: Theme.palette.baseFont.name
color: Theme.palette.directColor1
textFormat: Text.RichText
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
wrapMode: statusSelectableText.multiline ? Text.WrapAtWordBoundaryOrAnywhere : TextEdit.NoWrap
Keys.forwardTo: [statusSelectableText]
onFocusChanged: {
if(!focus) {
flick.contentX = 0
flick.contentY = 0
}
}
onLinkActivated: statusSelectableText.linkActivated(link)
text: "<style>a:link { color: " + (!!hoveredLink ? statusSelectableText.hoveredLinkColor : Theme.palette.baseColor1) + "; }</style>" + statusSelectableText.text
}
}
}
}
+2 -4
View File
@@ -15,10 +15,8 @@ Slider {
leftPadding: 0
background: Rectangle {
id: bgRect
implicitWidth: 100
implicitHeight: 4
height: implicitHeight
implicitWidth: 100
color: {
if (statusSlider.value === statusSlider.to) {
return Theme.palette.primaryColor1
@@ -42,7 +40,7 @@ Slider {
handle: Rectangle {
x: statusSlider.leftPadding + statusSlider.visualPosition * (statusSlider.availableWidth - width / 2)
anchors.verticalCenter: bgRect.verticalCenter
anchors.verticalCenter: parent.verticalCenter
color: Theme.palette.white
implicitWidth: 28
implicitHeight: 28
@@ -1,53 +0,0 @@
import QtQuick 2.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Item {
id: root
property StatusIconSettings icon: StatusIconSettings {
width: 24
height: 24
name: ""
}
property bool highlighted: false
property bool enabled: true
signal clicked(var mouse)
implicitWidth: 40
implicitHeight: 40
MouseArea {
id: sensor
enabled: root.enabled
cursorShape: root.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
anchors.fill: parent
hoverEnabled: true
onClicked: function (mouse) {
root.clicked(mouse)
}
StatusIcon {
id: statusIcon
width: root.icon.width
height: root.icon.height
icon: root.icon.name
color: root.highlighted || sensor.containsMouse ? Theme.palette.primaryColor1 : Theme.palette.baseColor1
anchors.centerIn: parent
}
Rectangle {
visible: root.highlighted || sensor.containsMouse
width: statusIcon.width
anchors.horizontalCenter: parent.horizontalCenter
height: 2
radius: 1
color: Theme.palette.primaryColor1
anchors.bottom: parent.bottom
}
}
}

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