Compare commits

..
Author SHA1 Message Date
Pascal Precht 7136968b3a feat(StatusChatToolBar): add tooltips to action buttons
Closes #244
2021-07-09 16:10:16 +02:00
Pascal Precht cf6b745567 feat(StatusChatToolBar): add members and search button
This commit adds the members and search button which are needed for certain
features in Status Desktop. In views where these aren't needed, each button
can be set `visible: false` individually:

```qml
StatusChatToolBar {
    ...
    membersButton.visible: false
    searchButton.visible: false
}
```

Closes #243
2021-07-09 16:09:40 +02:00
Pascal Precht ac5c84529e fix(StatusChatList): ensure badge is also shown for one to one messages 2021-07-09 16:08:02 +02:00
Pascal Precht 096d4148cd chore: ensure StatusChatList receives the proper value for mentions
This is due to a change in how mentions and unread messages are indicated.
See https://github.com/status-im/status-desktop/commit/7fbccec227492c9c9f5188e1088e80304e1101fd for more information.
2021-07-09 14:56:24 +02:00
B.Melnik f2d36d3d80 fix(StatusBaseInput): Fix focus area
Closes: #241
2021-07-09 11:40:35 +02:00
Pascal Precht 8155d9a218 feat(StatusListItem): add Danger type support
Usage:

```qml
StatusListItem {
    title: "Some title"
    icon.name: "delete"
    type: StatusListItem.Type.Danger
}
```

Closes #248
2021-07-09 11:38:05 +02:00
Pascal Precht 70043c5be4 feat(StatusRoundIcon): enable icon.color support 2021-07-09 11:34:39 +02:00
Pascal Precht 531e54f238 feat(StatusListItem): support letter identicons
This adds support for letter identicons by using the `icon.isLetterIdenticon`
flag:

```qml
StatusListItem {
    title: "Some name"
    icon.isLetterIdenticon: true
    icon.background.color: "orange"
}
```

Closes #239
2021-07-09 11:34:25 +02:00
Alexandra Betouni 51a345866a [#202] Added Picker button
Adding picker button
* As an example it opens Qt's ColorDialog, as soon as
  a color is selected there, the button is colored
  with that. Final color picker to be implemented in
  a seperate task.

Also minor improvements in main.qml and sandbox.pro

Closes #202
2021-07-09 11:16:04 +02:00
Pascal Precht bd383e8746 feat(StatusModal): expose loaded content
As discussed in #237, this is needed for consumers to access content
children from outside `content`.

Usage:

```qml
StatusModal {
  id: modal
  content: StatusBaseText {
      text: "Foo"
  }

  rightButtons: [
      StatusButton {
          text: "Change text"
          onClicked: {
              modal.contentComponent.text = "Bar"
          }
      }
  ]
}
```

Fixes #237
2021-07-08 11:42:08 +02:00
B.Melnik 1321760442 feat(Controls): introduce StatusBaseInput
Usage: The same interface like TextField

Closes: #106
2021-07-08 11:30:31 +02:00
Pascal Precht 0072154f9f chore: add safety to satisfy QML 2021-07-06 12:30:00 +02:00
Pascal Precht 7dcec0cace fix(StatusChatInfoButton): make component identicon aware
Closes #228
2021-07-06 11:48:36 +02:00
Pascal Precht 144ac69d31 fix(StatusChatInfoButton): prefix chat name with "#" if needed
Closes #229
2021-07-06 11:48:20 +02:00
Pascal Precht 7b2030c6ab fix(StatusChatInfoButton): vertically center title if no subtitle is provided
Closes #230
2021-07-06 11:48:07 +02:00
Pascal Precht f7e38c9c72 fix(StatusChatInfoButton): disable hover effects when sensor is disabled
Closes #231
2021-07-06 11:47:52 +02:00
Pascal Precht cbdaf12814 fix(StatusChatListCategory): only try open popup when supplied
Closes #220
2021-07-02 14:28:40 +02:00
Pascal Precht 53d63a9b01 fix(StatusChatListAndCategories): make chat list visibily flag work
Closes #217
2021-07-02 14:28:29 +02:00
Pascal Precht 722d92c012 fix(StatusChatList): ensure popupMenu closeHandler don't break
These broke because we were referring to a `highlighted` property that
was wrongly scoped.

Fixes #216
2021-07-02 14:28:17 +02:00
Pascal Precht a9ae426cf5 fix(StatusChatListAndCategories): ensure chatItemUnmuted event is propagated
Closes #219
2021-07-02 14:28:05 +02:00
Pascal Precht 23ddbc2e0d fix(StatusChatListAndCategories): ensure chat list receives popup menu
Closes #218
2021-07-02 14:27:56 +02:00
Pascal Precht a664f635a7 feat(StatusChatList): expose hook to lazily calculate chat item names 2021-06-30 16:12:21 +02:00
Pascal Precht fd7a5530cf fix(StatusMenuSeparator): ensure height is 0 when invisible or disabled
Closes #212
2021-06-30 13:38:21 +02:00
Pascal Precht f7f217ed22 fix(StatusChatList): use fallback property to determine unread message count 2021-06-30 13:38:12 +02:00
Pascal Precht 3b11a1a81c chore(README): re-add sandbox app instructions
Those have been accidentally removed in previous commits.
2021-06-29 13:43:31 +02:00
Iuri Matias 171b14bf40 Update README.md 2021-06-29 06:49:41 -04:00
Pascal Precht 0a8517e8a4 chore(README): add table of components 2021-06-29 11:55:41 +02:00
B.Melnik 71d0ef7f6a fix: Add missing .qml to resources, add qmlcache to gitignore 2021-06-29 09:47:47 +02:00
B.Melnik f4e6b3da8a bug(StatusLoadingIndicator): Change Animator to Animation
Closes: #188
2021-06-29 09:46:23 +02:00
Pascal Precht 34df0f0dab fix(StatusChatListItem): ensure chat name elides when it's too long
Closes #151
2021-06-29 09:46:08 +02:00
Pascal Precht 141872c2a5 fix(StatusChatListItem): ensure public chat names are prefixed with '#'
Closes #191
2021-06-25 12:42:19 +02:00
Pascal Precht a98bae48dd refactor(StatusPopupMenu): expose category and chat id via open handler
Closes #192
2021-06-25 12:42:08 +02:00
Pascal Precht 7a2648f69f feat(StatusRoundedImage): introduce identicon support
This just introduces a new `StatusImageSettings` property `isIdenticon`
which can be used to determine whether a `StatusRoundedImage` should
render with a background + border (which is the case for identicons).

It also updates the `StatusChatList` delegate to consider that property
and have it properly decide how to render the UI.

Closes #173
2021-06-24 16:27:25 +02:00
Pascal Precht cfacd5be6d feat(StatusChatList): introduce profileImageFn property
This property enables users to pass as factory function to `StatusChatList`
component that determines the profile image of a given chat id.

Usage:

```qml
import StatusQ.Components 0.1

StatusChatList {
    ...
    profileImageFn: function (id) {
        // `id` is the model id of the current chat item iterator
        return ... // has to return a profile image url
    }
}
```

In addition to this property, this commit also makes the component
expect an optional `model.identityImage` in case it's already provided.
That way, `profileImageFn` can be omitted.

Closes #174
2021-06-24 16:17:06 +02:00
Pascal Precht baa663cea6 feat(Components): introduce StatusContactRequestsIndicatorListItem
Usage:

```qml
import StatusQ.Components 0.1

StatusContactRequestsIndicatorListItem {
    title: "Contact requests"
    requestsCount: 3
    sensor.onClicked: ...
}
```

Closes #175
2021-06-24 16:09:58 +02:00
Pascal Precht 8ef2d0ee47 refactor: make chat component enum variants match protocol values
Closes #183
2021-06-24 16:02:17 +02:00
Pascal Precht a6262f0a34 feat(StatusChatList): introduce popupMenu property
Chat list items can open a context on right click as well, so `StatusChatList`
needs to provide an API for users to pass down a `StatusPopupMenu` accordingly.

This is now possible with a dedicated `popupMenu` proporty that can be
used as follows:

```qml
StatusChatList {
    ...
    popupMenu: StatusPopupMenu {

        property string chatId

        openHandler: function () {
            ...
        }

        StatusMenuItem {
            ...
        }
        ...
    }
}
```

As will all `popupMenu` properties in StatusQ component, having this explicit API
option enables us to have control over how triggering components (in this case chat
list items) behave when they open a context menu (e.g. keeping them highlighted as long
as the menu is active).

When defining a `chatId` property, `StatusChatList` will hydrate it with the id of
the chat list item that has triggered the menu.

If there's more logic to be executed upon opening the menu, `openHandler` serves
as a hook similar to other popup menus. Inside the hook, users have access to the
specific `chatId`.

Closes #171
2021-06-24 16:01:47 +02:00
Pascal Precht 75b2f508b3 fix(StatusModalHeader): ensure header has enough height for children
Closes #185
2021-06-24 16:00:30 +02:00
Pascal Precht 3d0688b778 fix(StatusRoundedImage): ensure images are scaled and positioned properly
Closes #172
2021-06-24 16:00:05 +02:00
Pascal Precht 70332a3f41 fix(StatusChatList): expect model.color instead of iconColor prop 2021-06-24 15:59:45 +02:00
Pascal Precht 300536bc5d fix(StatusChatList): ensure component provide default width
Closes #176
2021-06-24 15:59:21 +02:00
Pascal Precht 44343d3857 feat(StatusChatListItem): add highlighted property
Similar to other controls and components, chat list items can be in a
`highlighted` state, for example when popup menus are active.

Closes #178
2021-06-24 15:58:59 +02:00
Pascal Precht 34b35318bc fix(StatusListItem): ensure icon background in secondary type works correctly 2021-06-24 15:58:28 +02:00
Pascal Precht de2c36d0e9 fix(StatusModal): ensure modal footer uses correct theme color 2021-06-24 15:58:04 +02:00
Pascal Precht 615575800a chore(README): add StatusQ.Platforms to readme
Also adjust executable script for sandbox
2021-06-22 11:08:29 +02:00
B.Melnik 7bc7df8d1c feat(StatusIcon): Improvement of Icons 2021-06-22 11:02:06 +02:00
Pascal Precht 8a684a7d8a refactor: don't make StatusChatList scrollable by default
This is because we ran into issues where some component compositions
caused scrollviews to be nested which rendered them non-functional.

For now we're rolling back the idea of components being smart enough
to become scrollable by themselves and have StatusQ consumers handle
scroll behaviour.
2021-06-22 10:37:59 +02:00
B.Melnik e49b58b94d feat(Popups): Add StatusModal 2021-06-21 13:04:34 +02:00
Pascal Precht 148c30b991 feat(Popups): introduce StatusModalDivider 2021-06-21 13:04:34 +02:00
B.Melnik 9c2a5830f3 feat(Popups): Add StatusModalFooter 2021-06-21 13:04:30 +02:00
B.Melnik fa9bb7adc6 feat(Popups): Add status modal header 2021-06-21 12:58:00 +02:00
Pascal Precht 146218e0bb feat(StatusListItem): introduce primary and secondary types
Also enable `icon.rotation` via `StatusIconSettings.
2021-06-21 12:57:59 +02:00
43 changed files with 1718 additions and 818 deletions
+2
View File
@@ -10,3 +10,5 @@ bin
*.autosave
Makefile
.qmake.stash
*_qml.cpp
*_qmlcache.qrc
+6 -3
View File
@@ -1,6 +1,6 @@
# Status QML
# StatusQ
> An emerging reusable UI component library for Status applications.
> An emerging reusable QML UI component library for Status applications.
## Usage
@@ -12,6 +12,7 @@ These modules are:
- [StatusQ.Components](https://github.com/status-im/StatusQ/blob/master/src/StatusQ/Controls/qmldir)
- [StatusQ.Controls](https://github.com/status-im/StatusQ/blob/master/src/StatusQ/Components/qmldir)
- [StatusQ.Layout](https://github.com/status-im/StatusQ/blob/master/src/StatusQ/Layout/qmldir)
- [StatusQ.Platform](https://github.com/status-im/StatusQ/blob/master/src/StatusQ/Platform/qmldir)
- [StatusQ.Popups](https://github.com/status-im/StatusQ/blob/master/src/StatusQ/Popups/qmldir)
Provided components can be viewed and tested in the [sandbox application](#viewing-and-testing-components) that comes with this repository.
@@ -49,5 +50,7 @@ $ ./scripts/build
Once that is done, the sandbox can be started with the generated executable:
```
$ ./bin
$ ./bin/sandbox
```
More Documentation available on the [wiki](https://hackmd.io/@status-desktop/B1naRjxh_/%2FwFtiXvOiQqCdw2lk6gbOLA)
+248 -226
View File
@@ -1,239 +1,261 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import QtQuick.Dialogs 1.3
import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
Grid {
columns: 3
columnSpacing: 38
rowSpacing: 10
Column {
spacing: 10
Grid {
id: buttonGridWidth
columns: 3
columnSpacing: 38
rowSpacing: 10
horizontalItemAlignment: Grid.AlignHCenter
horizontalItemAlignment: Grid.AlignHCenter
// Large
StatusButton {
text: "Button"
// Large
StatusButton {
text: "Button"
}
StatusButton {
text: "Button"
enabled: false
}
StatusButton {
text: "Button"
loading: true
}
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Danger
}
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Danger
enabled: false
}
StatusButton {
text: "Button"
loading: true
type: StatusBaseButton.Type.Danger
}
StatusFlatButton {
text: "Button"
}
StatusFlatButton {
text: "Button"
enabled: false
}
StatusFlatButton {
text: "Button"
loading: true
}
StatusFlatButton {
text: "Button"
type: StatusBaseButton.Type.Danger
}
StatusFlatButton {
text: "Button"
type: StatusBaseButton.Type.Danger
enabled: false
}
StatusFlatButton {
text: "Button"
type: StatusBaseButton.Type.Danger
loading: true
}
// Small
StatusButton {
text: "Button"
size: StatusBaseButton.Size.Small
}
StatusButton {
text: "Button"
enabled: false
size: StatusBaseButton.Size.Small
}
StatusButton {
text: "Button"
size: StatusBaseButton.Size.Small
loading: true
}
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Danger
size: StatusBaseButton.Size.Small
}
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Danger
size: StatusBaseButton.Size.Small
enabled: false
}
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Danger
size: StatusBaseButton.Size.Small
loading: true
}
StatusFlatButton {
text: "Button"
size: StatusBaseButton.Size.Small
}
StatusFlatButton {
text: "Button"
enabled: false
size: StatusBaseButton.Size.Small
}
StatusFlatButton {
text: "Button"
enabled: false
size: StatusBaseButton.Size.Small
loading: true
}
// Icon buttons
// blue
StatusRoundButton {
icon.name: "info"
}
StatusRoundButton {
icon.name: "info"
enabled: false
}
StatusRoundButton {
icon.name: "info"
loading: true
}
// black
StatusRoundButton {
type: StatusRoundButton.Type.Secondary
icon.name: "info"
}
StatusRoundButton {
type: StatusRoundButton.Type.Secondary
icon.name: "info"
enabled: false
}
StatusRoundButton {
type: StatusRoundButton.Type.Secondary
icon.name: "info"
loading: true
}
// Rounded blue
StatusFlatRoundButton {
width: 44
height: 44
icon.name: "info"
}
StatusFlatRoundButton {
width: 44
height: 44
icon.name: "info"
enabled: false
}
StatusFlatRoundButton {
width: 44
height: 44
icon.name: "info"
loading: true
}
// Rounded white
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
width: 44
height: 44
icon.name: "info"
}
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
width: 44
height: 44
icon.name: "info"
enabled: false
}
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
width: 44
height: 44
icon.name: "info"
loading: true
}
StatusFlatButton {
icon.name: "info"
text: "Button"
size: StatusBaseButton.Size.Small
}
StatusFlatButton {
icon.name: "info"
text: "Button"
enabled: false
size: StatusBaseButton.Size.Small
}
StatusFlatButton {
icon.name: "info"
text: "Button"
loading: true
size: StatusBaseButton.Size.Small
}
}
StatusButton {
text: "Button"
enabled: false
}
StatusButton {
text: "Button"
loading: true
}
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Danger
}
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Danger
enabled: false
}
StatusButton {
text: "Button"
loading: true
type: StatusBaseButton.Type.Danger
}
StatusFlatButton {
text: "Button"
}
StatusFlatButton {
text: "Button"
enabled: false
}
StatusFlatButton {
text: "Button"
loading: true
}
StatusFlatButton {
text: "Button"
type: StatusBaseButton.Type.Danger
}
StatusFlatButton {
text: "Button"
type: StatusBaseButton.Type.Danger
enabled: false
}
StatusFlatButton {
text: "Button"
type: StatusBaseButton.Type.Danger
loading: true
}
// Small
StatusButton {
text: "Button"
size: StatusBaseButton.Size.Small
}
StatusButton {
text: "Button"
enabled: false
size: StatusBaseButton.Size.Small
}
StatusButton {
text: "Button"
size: StatusBaseButton.Size.Small
loading: true
}
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Danger
size: StatusBaseButton.Size.Small
}
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Danger
size: StatusBaseButton.Size.Small
enabled: false
}
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Danger
size: StatusBaseButton.Size.Small
loading: true
}
StatusFlatButton {
text: "Button"
size: StatusBaseButton.Size.Small
}
StatusFlatButton {
text: "Button"
enabled: false
size: StatusBaseButton.Size.Small
}
StatusFlatButton {
text: "Button"
enabled: false
size: StatusBaseButton.Size.Small
loading: true
}
// Icon buttons
// blue
StatusRoundButton {
icon.name: "info"
}
StatusRoundButton {
icon.name: "info"
enabled: false
}
StatusRoundButton {
icon.name: "info"
loading: true
}
// black
StatusRoundButton {
type: StatusRoundButton.Type.Secondary
icon.name: "info"
}
StatusRoundButton {
type: StatusRoundButton.Type.Secondary
icon.name: "info"
enabled: false
}
StatusRoundButton {
type: StatusRoundButton.Type.Secondary
icon.name: "info"
loading: true
}
// Rounded blue
StatusFlatRoundButton {
width: 44
height: 44
icon.name: "info"
}
StatusFlatRoundButton {
width: 44
height: 44
icon.name: "info"
enabled: false
}
StatusFlatRoundButton {
width: 44
height: 44
icon.name: "info"
loading: true
}
// Rounded white
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
width: 44
height: 44
icon.name: "info"
}
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
width: 44
height: 44
icon.name: "info"
enabled: false
}
StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
width: 44
height: 44
icon.name: "info"
loading: true
}
StatusFlatButton {
icon.name: "info"
text: "Button"
size: StatusBaseButton.Size.Small
}
StatusFlatButton {
icon.name: "info"
text: "Button"
enabled: false
size: StatusBaseButton.Size.Small
}
StatusFlatButton {
icon.name: "info"
text: "Button"
loading: true
size: StatusBaseButton.Size.Small
StatusPickerButton {
width: buttonGridWidth.width
bgColor: colorDialog.colorSelected ? colorDialog.color : Theme.palette.baseColor2
contentColor: colorDialog.colorSelected ? Theme.palette.indirectColor1 : Theme.palette.baseColor1
text: colorDialog.colorSelected ? colorDialog.color.toString().toUpperCase() : "Pick a color"
onClicked: {
colorDialog.open();
}
ColorDialog {
id: colorDialog
property bool colorSelected: false
onAccepted: {
colorSelected = true;
}
}
}
}
+30
View File
@@ -5,6 +5,8 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import Sandbox 0.1
GridLayout {
columns: 6
columnSpacing: 5
@@ -141,4 +143,32 @@ GridLayout {
to: 100
value: 40
}
StatusBaseInput {
placeholderText: "One line"
}
StatusBaseInput {
multiline: true
placeholderText: "Multiline"
}
StatusBaseInput {
multiline: true
placeholderText: "Multiline with static height"
implicitHeight: 100
}
Item {
implicitHeight: 300
implicitWidth: 300
StatusBaseInput {
anchors.centerIn: parent
multiline: true
placeholderText: "Multiline with max/min"
minimumHeight: 80
maximumHeight: 200
}
}
}
+313 -496
View File
@@ -1,8 +1,6 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import Sandbox 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
@@ -46,7 +44,6 @@ Rectangle {
}
}
StatusAppLayout {
id: statusAppLayout
anchors.top: demoApp.top
@@ -175,34 +172,74 @@ Rectangle {
text: "Chat"
}
StatusChatList {
width: parent.width
Column {
anchors.top: headline.bottom
anchors.topMargin: 16
anchors.bottom: parent.bottom
chatListItems.model: demoChatListItems
selectedChatId: "0"
onChatItemSelected: selectedChatId = id
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: demoChatListItems
selectedChatId: "0"
onChatItemSelected: selectedChatId = id
onChatItemUnmuted: {
for (var i = 0; i < demoChatListItems.count; i++) {
let item = demoChatListItems.get(i);
if (item.chatId === id) {
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
}
}
}
}
/* StatusChatListAndCategories { */
/* anchors.top: headline.bottom */
/* anchors.topMargin: 16 */
/* anchors.bottom: parent.bottom */
/* width: parent.width */
/* chatList.model: demoChatListItems */
/* selectedChatId: "0" */
/* onChatItemSelected: selectedChatId = id */
/* onChatItemUnmuted: { */
/* for (var i = 0; i < demoChatListItems.count; i++) { */
/* let item = demoChatListItems.get(i); */
/* if (item.chatId === id) { */
/* demoChatListItems.setProperty(i, "muted", false) */
/* } */
/* } */
/* } */
/* } */
}
rightPanel: Item {
@@ -218,6 +255,8 @@ Rectangle {
chatInfoButton.type: StatusChatInfoButton.Type.OneToOneChat
chatInfoButton.pinnedMessagesCount: 1
searchButton.visible: false
membersButton.visible: false
notificationCount: 1
onNotificationButtonClicked: notificationCount = 0
@@ -259,17 +298,20 @@ Rectangle {
StatusAppTwoPanelLayout {
leftPanel: Item {
id: leftPanel
anchors.fill: parent
StatusChatInfoToolBar {
id: statusChatInfoToolBar
anchors.top: parent.top
chatInfoButton.title: "Cryptokitties"
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
anchors.horizontalCenter: parent.horizontalCenter
chatInfoButton.onClicked: demoCommunityDetailModal.open()
popupMenu: StatusPopupMenu {
@@ -293,63 +335,105 @@ Rectangle {
}
}
StatusChatListAndCategories {
ScrollView {
id: scrollView
anchors.top: statusChatInfoToolBar.bottom
anchors.topMargin: 8
anchors.bottom: parent.bottom
width: parent.width
width: leftPanel.width
chatList.model: demoCommunityChatListItems
categoryList.model: demoCommunityCategoryItems
contentHeight: communityCategories.height
clip: true
showCategoryActionButtons: true
onChatItemSelected: selectedChatId = id
StatusChatListAndCategories {
id: communityCategories
height: implicitHeight > (leftPanel.height - 64) ? implicitHeight + 8 : leftPanel.height - 64
width: leftPanel.width
categoryPopupMenu: StatusPopupMenu {
chatList.model: demoCommunityChatListItems
categoryList.model: demoCommunityCategoryItems
property string categoryId
showCategoryActionButtons: true
onChatItemSelected: selectedChatId = id
StatusMenuItem {
text: "Mute Category"
icon.name: "notification"
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
}
}
StatusMenuItem {
text: "Mark as Read"
icon.name: "checkmark-circle"
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
}
}
StatusMenuItem {
text: "Edit Category"
icon.name: "edit"
}
popupMenu: StatusPopupMenu {
StatusMenuItem {
text: "Create channel"
icon.name: "channel"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Create category"
icon.name: "channel-category"
}
StatusMenuItem {
text: "Delete Category"
icon.name: "delete"
type: StatusMenuItem.Type.Danger
}
}
StatusMenuSeparator {}
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"
StatusMenuItem {
text: "Invite people"
icon.name: "share-ios"
}
}
}
}
@@ -443,6 +527,145 @@ Rectangle {
}
}
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"
}
content: StatusBaseText {
anchors.centerIn: parent
text: "Contact request will be shown here"
font.pixelSize: 15
color: Theme.palette.directColor1
}
rightButtons: [
StatusButton {
text: "Decline all"
type: StatusBaseButton.Type.Danger
onClicked: demoContactRequestsModal.close()
},
StatusButton {
text: "Accept all"
onClicked: demoContactRequestsModal.close()
}
]
}
StatusModal {
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"
content: 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
}
}
}
ListModel {
id: demoChatListItems
ListElement {
@@ -450,28 +673,27 @@ Rectangle {
name: "#status"
chatType: StatusChatListItem.Type.PublicChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "blue"
mentionsCount: 0
color: "blue"
}
ListElement {
chatId: "1"
name: "#status-desktop"
name: "status-desktop"
chatType: StatusChatListItem.Type.PublicChat
muted: false
hasUnreadMessages: true
iconColor: "red"
color: "red"
unreadMessagesCount: 1
mentionsCount: 1
}
ListElement {
chatId: "2"
name: "Amazing Funny Squirrel"
chatType: StatusChatListItem.Type.OneToOneChat
muted: false
hasUnreadMessages: false
iconColor: "green"
identicon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
color: "green"
identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
unreadMessagesCount: 0
}
ListElement {
@@ -479,8 +701,7 @@ Rectangle {
name: "Black Ops"
chatType: StatusChatListItem.Type.GroupChat
muted: false
hasUnreadMessages: false
iconColor: "purple"
color: "purple"
unreadMessagesCount: 0
}
ListElement {
@@ -488,196 +709,15 @@ Rectangle {
name: "Spectacular Growing Otter"
chatType: StatusChatListItem.Type.OneToOneChat
muted: true
hasUnreadMessages: false
iconColor: "Orange"
color: "Orange"
unreadMessagesCount: 0
}
ListElement {
chatId: "0"
name: "#status"
chatId: "5"
name: "channel-with-a-super-duper-long-name"
chatType: StatusChatListItem.Type.PublicChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "blue"
}
ListElement {
chatId: "1"
name: "#status-desktop"
chatType: StatusChatListItem.Type.PublicChat
muted: false
hasUnreadMessages: true
iconColor: "red"
unreadMessagesCount: 1
}
ListElement {
chatId: "2"
name: "Amazing Funny Squirrel"
chatType: StatusChatListItem.Type.OneToOneChat
muted: false
hasUnreadMessages: false
iconColor: "green"
identicon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
unreadMessagesCount: 0
}
ListElement {
chatId: "3"
name: "Black Ops"
chatType: StatusChatListItem.Type.GroupChat
muted: false
hasUnreadMessages: false
iconColor: "purple"
unreadMessagesCount: 0
}
ListElement {
chatId: "4"
name: "Spectacular Growing Otter"
chatType: StatusChatListItem.Type.OneToOneChat
muted: true
hasUnreadMessages: false
iconColor: "Orange"
unreadMessagesCount: 0
}
ListElement {
chatId: "0"
name: "#status"
chatType: StatusChatListItem.Type.PublicChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "blue"
}
ListElement {
chatId: "1"
name: "#status-desktop"
chatType: StatusChatListItem.Type.PublicChat
muted: false
hasUnreadMessages: true
iconColor: "red"
unreadMessagesCount: 1
}
ListElement {
chatId: "2"
name: "Amazing Funny Squirrel"
chatType: StatusChatListItem.Type.OneToOneChat
muted: false
hasUnreadMessages: false
iconColor: "green"
identicon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
unreadMessagesCount: 0
}
ListElement {
chatId: "3"
name: "Black Ops"
chatType: StatusChatListItem.Type.GroupChat
muted: false
hasUnreadMessages: false
iconColor: "purple"
unreadMessagesCount: 0
}
ListElement {
chatId: "4"
name: "Spectacular Growing Otter"
chatType: StatusChatListItem.Type.OneToOneChat
muted: true
hasUnreadMessages: false
iconColor: "Orange"
unreadMessagesCount: 0
}
ListElement {
chatId: "0"
name: "#status"
chatType: StatusChatListItem.Type.PublicChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "blue"
}
ListElement {
chatId: "1"
name: "#status-desktop"
chatType: StatusChatListItem.Type.PublicChat
muted: false
hasUnreadMessages: true
iconColor: "red"
unreadMessagesCount: 1
}
ListElement {
chatId: "2"
name: "Amazing Funny Squirrel"
chatType: StatusChatListItem.Type.OneToOneChat
muted: false
hasUnreadMessages: false
iconColor: "green"
identicon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
unreadMessagesCount: 0
}
ListElement {
chatId: "3"
name: "Black Ops"
chatType: StatusChatListItem.Type.GroupChat
muted: false
hasUnreadMessages: false
iconColor: "purple"
unreadMessagesCount: 0
}
ListElement {
chatId: "4"
name: "Spectacular Growing Otter"
chatType: StatusChatListItem.Type.OneToOneChat
muted: true
hasUnreadMessages: false
iconColor: "Orange"
unreadMessagesCount: 0
}
ListElement {
chatId: "0"
name: "#status"
chatType: StatusChatListItem.Type.PublicChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "blue"
}
ListElement {
chatId: "1"
name: "#status-desktop"
chatType: StatusChatListItem.Type.PublicChat
muted: false
hasUnreadMessages: true
iconColor: "red"
unreadMessagesCount: 1
}
ListElement {
chatId: "2"
name: "Amazing Funny Squirrel"
chatType: StatusChatListItem.Type.OneToOneChat
muted: false
hasUnreadMessages: false
iconColor: "green"
identicon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
unreadMessagesCount: 0
}
ListElement {
chatId: "3"
name: "Black Ops"
chatType: StatusChatListItem.Type.GroupChat
muted: false
hasUnreadMessages: false
iconColor: "purple"
unreadMessagesCount: 0
}
ListElement {
chatId: "4"
name: "Spectacular Growing Otter"
chatType: StatusChatListItem.Type.OneToOneChat
muted: true
hasUnreadMessages: false
iconColor: "Orange"
color: "green"
unreadMessagesCount: 0
}
}
@@ -689,20 +729,16 @@ Rectangle {
name: "general"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
color: "orange"
}
ListElement {
chatId: "1"
name: "random"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
color: "orange"
categoryId: "public"
}
ListElement {
@@ -710,10 +746,8 @@ Rectangle {
name: "watercooler"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
color: "orange"
categoryId: "public"
}
ListElement {
@@ -721,225 +755,8 @@ Rectangle {
name: "language-design"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "dev"
}
ListElement {
chatId: "0"
name: "general"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
}
ListElement {
chatId: "1"
name: "random"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "public"
}
ListElement {
chatId: "2"
name: "watercooler"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "public"
}
ListElement {
chatId: "3"
name: "language-design"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "dev"
}
ListElement {
chatId: "0"
name: "general"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
}
ListElement {
chatId: "1"
name: "random"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "public"
}
ListElement {
chatId: "2"
name: "watercooler"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "public"
}
ListElement {
chatId: "3"
name: "language-design"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "dev"
}
ListElement {
chatId: "0"
name: "general"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
}
ListElement {
chatId: "1"
name: "random"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "public"
}
ListElement {
chatId: "2"
name: "watercooler"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "public"
}
ListElement {
chatId: "3"
name: "language-design"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "dev"
}
ListElement {
chatId: "0"
name: "general"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
}
ListElement {
chatId: "1"
name: "random"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "public"
}
ListElement {
chatId: "2"
name: "watercooler"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "public"
}
ListElement {
chatId: "3"
name: "language-design"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "dev"
}
ListElement {
chatId: "0"
name: "general"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
}
ListElement {
chatId: "1"
name: "random"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "public"
}
ListElement {
chatId: "2"
name: "watercooler"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
categoryId: "public"
}
ListElement {
chatId: "3"
name: "language-design"
chatType: StatusChatListItem.Type.CommunityChat
muted: false
hasUnreadMessages: false
hasMention: false
unreadMessagesCount: 0
iconColor: "orange"
color: "orange"
categoryId: "dev"
}
}
+22
View File
@@ -224,6 +224,24 @@ GridLayout {
]
}
StatusListItem {
title: "Title"
icon.name: "info"
type: StatusListItem.Type.Secondary
}
StatusListItem {
title: "Title"
icon.isLetterIdenticon: true
icon.background.color: "orange"
}
StatusListItem {
title: "Title"
icon.name: "delete"
type: StatusListItem.Type.Danger
}
StatusDescriptionListItem {
title: "Title"
subTitle: "Subtitle"
@@ -237,4 +255,8 @@ GridLayout {
iconButton.onClicked: tooltip.visible = !tooltip.visible
}
StatusContactRequestsIndicatorListItem {
title: "Contact requests"
requestsCount: 3
}
}
+174
View File
@@ -0,0 +1,174 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Popups 0.1
Column {
spacing: 20
StatusButton {
text: "Simple modal"
onClicked: simpleModal.open()
}
StatusButton {
text: "Modal with header image"
onClicked: headerImageModal.open()
}
StatusButton {
text: "Modal with footer buttons"
onClicked: footerButtonsModal.open()
}
StatusButton {
text: "Modal with header action button"
onClicked: headerActionButtonModal.open()
}
StatusButton {
text: "Modal with content"
onClicked: modalExample.open()
}
StatusButton {
text: "Modal with changable content"
onClicked: modalWithContentAccess.open()
}
StatusModal {
id: simpleModal
anchors.centerIn: parent
header.title: "Some Title"
header.subTitle: "Subtitle"
}
StatusModal {
id: headerImageModal
anchors.centerIn: parent
header.title: "Some Title"
header.subTitle: "Subtitle"
header.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
}
StatusModal {
id: footerButtonsModal
anchors.centerIn: parent
header.title: "Some Title"
header.subTitle: "Subtitle"
header.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
leftButtons: [
StatusRoundButton {
icon.name: "arrow-right"
rotation: 180
}
]
rightButtons: [
StatusButton {
text: "Button"
},
StatusButton {
text: "Button"
}
]
}
StatusModal {
id: headerActionButtonModal
anchors.centerIn: parent
header.title: "Some Title"
header.subTitle: "Subtitle"
header.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
headerActionButton: StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
width: 32
height: 32
icon.width: 20
icon.height: 20
icon.name: "info"
}
leftButtons: [
StatusRoundButton {
icon.name: "arrow-right"
rotation: 180
}
]
rightButtons: [
StatusButton {
text: "Button"
},
StatusButton {
text: "Button"
}
]
}
StatusModal {
id: modalExample
anchors.centerIn: parent
header.image.source: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
header.title: "Header"
header.subTitle: "SubTitle"
rightButtons: [
StatusButton {
text: "Button"
},
StatusButton {
text: "Button"
}
]
leftButtons: [
StatusRoundButton {
icon.name: "arrow-right"
rotation: 180
}
]
content: StatusBaseText {
anchors.centerIn: parent
text: "Some text content"
font.pixelSize: 15
color: Theme.palette.directColor1
}
headerActionButton: StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
width: 32
height: 32
icon.width: 20
icon.height: 20
icon.name: "info"
}
}
StatusModal {
id: modalWithContentAccess
anchors.centerIn: parent
header.title: "Header"
header.subTitle: "SubTitle"
content: StatusBaseText {
id: text
anchors.centerIn: parent
text: "Some text content"
font.pixelSize: 15
color: Theme.palette.directColor1
}
rightButtons: [
StatusButton {
text: "Change text"
onClicked: {
modalWithContentAccess.contentComponent.text = "Changed!"
}
}
]
}
}
+13 -4
View File
@@ -165,6 +165,12 @@ StatusWindow {
selected: page.sourceComponent == popupMenuComponent
onClicked: page.sourceComponent = popupMenuComponent
}
StatusNavigationListItem {
title: "StatusModal"
selected: page.sourceComponent == statusModalComponent
onClicked: page.sourceComponent = statusModalComponent
}
}
}
}
@@ -172,12 +178,10 @@ StatusWindow {
rightPanel: Item {
id: rightPanel
anchors.fill: parent
ScrollView {
width: parent.width
height: parent.height
anchors.fill: parent
contentHeight: (pageWrapper.height + pageWrapper.anchors.topMargin) * rootWindow.factor
contentWidth: pageWrapper.width * rootWindow.factor
contentWidth: (pageWrapper.width * rootWindow.factor)
clip: true
Item {
@@ -262,6 +266,11 @@ StatusWindow {
StatusChatInfoToolBarPage {}
}
Component {
id: statusModalComponent
Popups {}
}
Component {
id: demoAppCmp
+1
View File
@@ -11,5 +11,6 @@
<file>StatusPopupMenuPage.qml</file>
<file>ThemeSwitch.qml</file>
<file>Layout.qml</file>
<file>Popups.qml</file>
</qresource>
</RCC>
+2 -9
View File
@@ -53,15 +53,8 @@ HEADERS += \
sandboxapp.h \
statuswindow.h
DISTFILES += \
../src/StatusQ/Components/StatusMacWindowButtons.qml \
../src/StatusQ/Controls/StatusBaseButton.qml \
../src/StatusQ/Controls/StatusButton.qml \
../src/StatusQ/Controls/StatusCheckBox.qml \
../src/StatusQ/Controls/StatusFlatRoundButton.qml \
../src/StatusQ/Controls/StatusRadioButton.qml \
../src/StatusQ/Controls/StatusSlider.qml \
../src/StatusQ/Controls/StatusSwitch.qml
OTHER_FILES += $$files($$PWD/../*.qml, true)
OTHER_FILES += $$files($$PWD/*.qml, true)
android {
+79 -27
View File
@@ -1,52 +1,104 @@
import QtQuick 2.13
import QtQuick.Controls 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
ScrollView {
Column {
id: statusChatList
contentHeight: items.height + 8
clip: true
spacing: 4
width: 288
property string categoryId: ""
property string selectedChatId: ""
property alias chatListItems: statusChatListItems
property Component popupMenu
property var filterFn
property var profileImageFn
property var chatNameFn
signal chatItemSelected(string id)
signal chatItemUnmuted(string id)
Column {
id: items
spacing: 4
Repeater {
id: statusChatListItems
delegate: StatusChatListItem {
chatId: model.chatId
name: model.name
type: model.chatType
muted: !!model.muted
hasUnreadMessages: !!model.hasUnreadMessages
hasMention: !!model.hasMention
badge.value: model.unreadMessagesCount || 0
selected: model.chatId === statusChatList.selectedChatId
onPopupMenuChanged: {
if (!!popupMenu) {
popupMenuSlot.sourceComponent = popupMenu
}
}
icon.color: model.iconColor || ""
image.source: model.identicon || ""
Repeater {
id: statusChatListItems
delegate: StatusChatListItem {
onClicked: statusChatList.chatItemSelected(model.chatId)
onUnmute: statusChatList.chatItemUnmuted(model.chatId)
visible: {
if (!!statusChatList.filterFn) {
return statusChatList.filterFn(model, statusChatList.categoryId)
}
return true
id: statusChatListItem
property string profileImage: ""
Component.onCompleted: {
if (typeof statusChatList.profileImageFn === "function") {
profileImage = statusChatList.profileImageFn(model.chatId || model.id) || ""
}
}
chatId: model.chatId || model.id
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 || ""
onClicked: {
if (mouse.button === Qt.RightButton && !!statusChatList.popupMenu) {
statusChatListItem.highlighted = true
let originalOpenHandler = popupMenuSlot.item.openHandler
let originalCloseHandler = popupMenuSlot.item.closeHandler
popupMenuSlot.item.openHandler = function () {
if (!!originalOpenHandler) {
originalOpenHandler((model.chatId || model.id))
}
}
popupMenuSlot.item.closeHandler = function () {
if (statusChatListItem) {
statusChatListItem.highlighted = false
}
if (!!originalCloseHandler) {
originalCloseHandler()
}
}
popupMenuSlot.item.popup(mouse.x + 4, statusChatListItem.y + mouse.y + 6)
popupMenuSlot.item.openHandler = originalOpenHandler
return
}
statusChatList.chatItemSelected(model.chatId || model.id)
}
onUnmute: statusChatList.chatItemUnmuted(model.chatId || model.id)
visible: {
if (!!statusChatList.filterFn) {
return statusChatList.filterFn(model, statusChatList.categoryId)
}
return true
}
}
}
Loader {
id: popupMenuSlot
active: !!statusChatList.popupMenu
}
}
@@ -4,11 +4,11 @@ import QtQuick.Controls 2.14
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
ScrollView {
Item {
id: statusChatListAndCategories
clip: true
contentHeight: chatListsAndCategories.height + 8
implicitHeight: chatListsAndCategories.height
implicitWidth: chatListsAndCategories.width
property string selectedChatId: ""
property bool showCategoryActionButtons: false
@@ -17,6 +17,7 @@ ScrollView {
property alias sensor: sensor
property Component categoryPopupMenu
property Component chatListPopupMenu
property Component popupMenu
signal chatItemSelected(string id)
@@ -32,7 +33,7 @@ ScrollView {
MouseArea {
id: sensor
anchors.top: parent.top
width: parent.width
width: statusChatListAndCategories.width
height: statusChatListAndCategories.height
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
@@ -52,13 +53,14 @@ ScrollView {
StatusChatList {
id: statusChatList
anchors.horizontalCenter: parent.horizontalCenter
visible: !!chatListItems.model && chatListItems.model.count > 0
visible: !!chatListItems.model && chatListItems.count > 0
selectedChatId: statusChatListAndCategories.selectedChatId
onChatItemSelected: statusChatListAndCategories.chatItemSelected(id)
onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id)
filterFn: function (model) {
return !!!model.categoryId
}
popupMenu: statusChatListAndCategories.chatListPopupMenu
}
Repeater {
@@ -74,8 +76,10 @@ ScrollView {
chatList.chatListItems.model: statusChatListAndCategories.chatList.model
chatList.selectedChatId: statusChatListAndCategories.selectedChatId
chatList.onChatItemSelected: statusChatListAndCategories.chatItemSelected(id)
chatList.onChatItemUnmuted: statusChatListAndCategories.chatItemUnmuted(id)
popupMenu: statusChatListAndCategories.categoryPopupMenu
chatListPopupMenu: statusChatListAndCategories.chatListPopupMenu
}
}
}
@@ -18,6 +18,7 @@ Column {
property alias toggleButton: statusChatListCategoryItem.toggleButton
property alias chatList: statusChatList
property Component chatListPopupMenu
property Component popupMenu
onPopupMenuChanged: {
@@ -34,7 +35,7 @@ Column {
showMenuButton: !!statusChatListCategory.popupMenu
onClicked: {
if (mouse.button === Qt.RightButton) {
if (mouse.button === Qt.RightButton && !!statusChatListCategory.popupMenu) {
highlighted = true
popupMenuSlot.item.popup(mouse.x + 4, mouse.y + 6)
return
@@ -59,20 +60,29 @@ Column {
filterFn: function (model) {
return !!model.categoryId && model.categoryId == statusChatList.categoryId
}
popupMenu: statusChatListCategory.chatListPopupMenu
}
Loader {
id: popupMenuSlot
active: !!statusChatListCategory.popupMenu
onLoaded: {
let originalOpenHandler = popupMenuSlot.item.openHandler
let originalCloseHandler = popupMenuSlot.item.closeHandler
popupMenuSlot.item.openHandler = function () {
if (popupMenuSlot.item.hasOwnProperty('categoryId')) {
popupMenuSlot.item.categoryId = statusChatListCategory.categoryId
if (!!originalOpenHandler) {
originalOpenHandler(statusChatListCategory.categoryId)
}
}
popupMenuSlot.item.closeHandler = function () {
statusChatListCategoryItem.highlighted = false
statusChatListCategoryItem.menuButton.highlighted = false
if (!!originalCloseHandler) {
originalCloseHandler()
}
}
}
}
+28 -9
View File
@@ -18,19 +18,23 @@ Rectangle {
color: Theme.palette.miscColor5
}
property int type: StatusChatListItem.Type.PublicChat
property bool highlighted: false
property bool selected: false
signal clicked(var mouse)
signal unmute()
enum Type {
PublicChat,
GroupChat,
CommunityChat,
OneToOneChat
Unknown0, // 0
OneToOneChat, // 1
PublicChat, // 2
GroupChat, // 3
Unknown1, // 4
Unknown2, // 5
CommunityChat // 6
}
implicitWidth: 287
implicitWidth: 288
implicitHeight: 40
radius: 8
@@ -39,7 +43,7 @@ Rectangle {
if (selected) {
return Theme.palette.statusChatListItem.selectedBackgroundColor
}
return sensor.containsMouse ? Theme.palette.statusChatListItem.hoverBackgroundColor : Theme.palette.baseColor4
return sensor.containsMouse || highlighted ? Theme.palette.statusChatListItem.hoverBackgroundColor : Theme.palette.baseColor4
}
MouseArea {
@@ -47,6 +51,7 @@ Rectangle {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled: true
onClicked: statusChatListItem.clicked(mouse)
@@ -83,6 +88,11 @@ Rectangle {
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 {
@@ -101,12 +111,13 @@ Rectangle {
width: 14
visible: statusChatListItem.type !== StatusChatListItem.Type.OneToOneChat
opacity: {
if (statusChatListItem.muted && !sensor.containsMouse) {
if (statusChatListItem.muted && !sensor.containsMouse && !statusChatListItem.highlighted) {
return 0.4
}
return statusChatListItem.hasMention ||
statusChatListItem.hasUnreadMessages ||
statusChatListItem.selected ||
statusChatListItem.highlighted ||
statusBadge.visible ||
sensor.containsMouse ? 1.0 : 0.7
}
@@ -132,16 +143,24 @@ Rectangle {
id: chatName
anchors.left: statusIcon.visible ? statusIcon.right : identicon.right
anchors.leftMargin: statusIcon.visible ? 1 : 8
anchors.right: statusBadge.visible ? statusBadge.left :
mutedIcon.visible ? mutedIcon.left : parent.right
anchors.rightMargin: 6
anchors.verticalCenter: parent.verticalCenter
text: statusChatListItem.name
text: statusChatListItem.type === StatusChatListItem.Type.PublicChat &&
!statusChatListItem.name.startsWith("#") ?
"#" + statusChatListItem.name :
statusChatListItem.name
elide: Text.ElideRight
color: {
if (statusChatListItem.muted && !sensor.containsMouse) {
if (statusChatListItem.muted && !sensor.containsMouse && !statusChatListItem.highlighted) {
return Theme.palette.directColor5
}
return statusChatListItem.hasMention ||
statusChatListItem.hasUnreadMessages ||
statusChatListItem.selected ||
statusChatListItem.highlighted ||
sensor.containsMouse ||
statusBadge.visible ? Theme.palette.directColor1 : Theme.palette.directColor4
}
+62 -12
View File
@@ -14,6 +14,8 @@ Rectangle {
property alias chatInfoButton: statusChatInfoButton
property alias menuButton: menuButton
property alias notificationButton: notificationButton
property alias membersButton: membersButton
property alias searchButton: searchButton
property int notificationCount: 0
property Component popupMenu
@@ -21,6 +23,8 @@ Rectangle {
signal chatInfoButtonClicked()
signal menuButtonClicked()
signal notificationButtonClicked()
signal membersButtonClicked()
signal searchButtonClicked()
onPopupMenuChanged: {
if (!!popupMenu) {
@@ -44,6 +48,38 @@ Rectangle {
spacing: 8
StatusFlatRoundButton {
id: searchButton
width: 32
height: 32
icon.name: "search"
type: StatusFlatRoundButton.Type.Secondary
onClicked: statusChatToolBar.searchButtonClicked()
StatusToolTip {
visible: !!text && parent.hovered
text: "Search"
orientation: StatusToolTip.Orientation.Bottom
y: parent.height + 12
}
}
StatusFlatRoundButton {
id: membersButton
width: 32
height: 32
icon.name: "group-chat"
type: StatusFlatRoundButton.Type.Secondary
onClicked: statusChatToolBar.membersButtonClicked()
StatusToolTip {
visible: !!text && parent.hovered
text: "Members"
orientation: StatusToolTip.Orientation.Bottom
y: parent.height + 12
}
}
StatusFlatRoundButton {
id: menuButton
width: 32
@@ -55,8 +91,24 @@ Rectangle {
onClicked: {
statusChatToolBar.menuButtonClicked()
highlighted = true
let p = menuButton.mapToItem(statusChatToolBar, menuButton.x, menuButton.y)
popupMenuSlot.item.popup(p.x + menuButton.width - popupMenuSlot.item.width, p.y + 4 + menuButton.height)
popupMenuSlot.item.popup(-popupMenuSlot.item.width + menuButton.width, menuButton.height + 4)
}
StatusToolTip {
visible: !!text && parent.hovered && !popupMenuSlot.item.opened
text: "More"
orientation: StatusToolTip.Orientation.Bottom
y: parent.height + 12
}
Loader {
id: popupMenuSlot
active: !!statusChatToolBar.popupMenu
onLoaded: {
popupMenuSlot.item.closeHandler = function () {
menuButton.highlighted = false
}
}
}
}
@@ -65,7 +117,8 @@ Rectangle {
width: 1
color: Theme.palette.directColor7
anchors.verticalCenter: parent.verticalCenter
visible: menuButton.visible && notificationButton.visible
visible: notificationButton.visible &&
(menuButton.visible || membersButton.visible || searchButton.visible)
}
StatusFlatRoundButton {
@@ -100,18 +153,15 @@ Rectangle {
border.width: 2
border.color: parent.hovered ? Theme.palette.baseColor2 : Theme.palette.statusAppLayout.backgroundColor
}
}
}
Loader {
id: popupMenuSlot
active: !!statusChatToolBar.popupMenu
onLoaded: {
popupMenuSlot.item.closeHandler = function () {
menuButton.highlighted = false
StatusToolTip {
visible: !!text && parent.hovered
text: "Activity"
orientation: StatusToolTip.Orientation.Bottom
y: parent.height + 12
}
}
}
}
@@ -0,0 +1,30 @@
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
StatusListItem {
id: statusContactRequestsListItem
implicitHeight: 64
implicitWidth: 288
color: sensor.containsMouse ? Theme.palette.baseColor2 : "transparent"
property int requestsCount: 0
components: [
StatusBadge {
value: statusContactRequestsListItem.requestsCount
anchors.verticalCenter: parent.verticalCenter
border.width: 4
border.color: color
},
StatusIcon {
icon: "chevron-down"
rotation: 270
color: Theme.palette.baseColor1
}
]
}
+66 -5
View File
@@ -10,7 +10,26 @@ Rectangle {
implicitWidth: 448
implicitHeight: 64
color: sensor.containsMouse ? Theme.palette.baseColor2 : Theme.palette.statusListItem.backgroundColor
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 title: ""
@@ -20,10 +39,22 @@ Rectangle {
property StatusIconSettings icon: StatusIconSettings {
height: 20
width: 20
rotation: 0
isLetterIdenticon: false
color: type === StatusListItem.Type.Danger ?
Theme.palette.dangerColor1 : Theme.palette.primaryColor1
background: StatusIconBackgroundSettings {
width: 40
height: 40
color: Theme.palette.primaryColor3
color: {
if (sensor.containsMouse) {
return type === StatusListItem.Type.Secondary ||
type === StatusListItem.Type.Danger ? "transparent" :
Theme.palette.primaryColor3
}
return type === StatusListItem.Type.Danger ?
Theme.palette.dangerColor3 : Theme.palette.primaryColor3
}
}
}
property StatusImageSettings image: StatusImageSettings {
@@ -32,6 +63,8 @@ Rectangle {
}
property string label: ""
property int type: StatusListItem.Type.Primary
property alias sensor: sensor
property alias statusListItemTitle: statusListItemTitle
property alias statusListItemSubTitle: statusListItemSubTitle
@@ -60,8 +93,15 @@ Rectangle {
anchors.left: parent.left
anchors.leftMargin: statusListItem.leftPadding
anchors.verticalCenter: parent.verticalCenter
sourceComponent: !!statusListItem.icon.name ? statusRoundedIcon : statusRoundedImage
active: !!statusListItem.icon.name || !!statusListItem.image.source.toString()
sourceComponent: {
if (statusListItem.icon.isLetterIdenticon) {
return statusLetterIdenticon
}
return !!statusListItem.icon.name ? statusRoundedIcon : statusRoundedImage
}
active: statusListItem.icon.isLetterIdenticon ||
!!statusListItem.icon.name ||
!!statusListItem.image.source.toString()
}
Component {
@@ -70,6 +110,8 @@ Rectangle {
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
@@ -85,6 +127,16 @@ Rectangle {
}
}
Component {
id: statusLetterIdenticon
StatusLetterIdenticon {
width: statusListItem.icon.background.width
height: statusListItem.icon.background.height
color: statusListItem.icon.background.color
name: statusListItem.title
}
}
Item {
anchors.left: iconOrImage.active ? iconOrImage.right : parent.left
anchors.leftMargin: statusListItem.leftPadding
@@ -95,7 +147,16 @@ Rectangle {
id: statusListItemTitle
text: statusListItem.title
font.pixelSize: 15
color: Theme.palette.directColor1
color: {
switch (statusListItem.type) {
case StatusListItem.Type.Primary:
return Theme.palette.directColor1
case StatusListItem.Type.Secondary:
return Theme.palette.primaryColor1
case StatusListItem.Type.Danger:
return Theme.palette.dangerColor1
}
}
}
StatusBaseText {
@@ -6,7 +6,7 @@ StatusIcon {
icon: "loading"
height: 17
width: 17
RotationAnimator {
RotationAnimation {
target: statusIcon;
from: 0;
to: 360;
+4 -1
View File
@@ -8,6 +8,8 @@ Rectangle {
property StatusIconSettings icon: StatusIconSettings {
width: 24
height: 24
rotation: 0
color: Theme.palette.primaryColor1
background: StatusIconBackgroundSettings {
width: 40
height: 40
@@ -28,7 +30,8 @@ Rectangle {
width: statusRoundedIcon.icon.width
height: statusRoundedIcon.icon.height
color: Theme.palette.primaryColor1
color: statusRoundedIcon.icon.color
icon: statusRoundedIcon.icon.name
rotation: statusRoundedIcon.icon.rotation
}
}
@@ -26,9 +26,12 @@ Rectangle {
Image {
id: image
sourceSize.width: parent.implicitWidth
sourceSize.height: parent.implicitHeight
width: statusRoundImage.width
height: statusRoundImage.height
sourceSize.width: parent.width * 2
sourceSize.height: parent.height * 2
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
cache: true
}
+1
View File
@@ -8,6 +8,7 @@ StatusChatListCategory 0.1 StatusChatListCategory.qml
StatusChatListCategoryItem 0.1 StatusChatListCategoryItem.qml
StatusChatListAndCategories 0.1 StatusChatListAndCategories.qml
StatusChatToolBar 0.1 StatusChatToolBar.qml
StatusContactRequestsIndicatorListItem 0.1 StatusContactRequestsIndicatorListItem.qml
StatusDescriptionListItem 0.1 StatusDescriptionListItem.qml
StatusLetterIdenticon 0.1 StatusLetterIdenticon.qml
StatusListItem 0.1 StatusListItem.qml
+153
View File
@@ -0,0 +1,153 @@
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: statusBaseInput
property bool multiline: false
property bool clearable: false
property alias inputMethodHints: edit.inputMethodHints
property alias selectedText: edit.selectedText
property alias selectedTextColor: edit.selectedTextColor
property alias selectionStart: edit.selectionStart
property alias selectionEnd: edit.selectionEnd
property alias color: edit.color
property alias font: edit.font
property alias verticalAlignmet: edit.verticalAlignment
property alias horizontalAlignment: edit.horizontalAlignment
property alias placeholderText: placeholder.text
property alias placeholderTextColor: placeholder.color
property alias placeholderFont: placeholder.font
property real leftPadding: 16
property real rightPadding: 16
property real topPadding: 11
property real bottomPadding: 11
property real minimumHeight: 0
property real maximumHeight: 0
implicitWidth: 200
implicitHeight: multiline ? Math.max(edit.implicitHeight + topPadding + bottomPadding, 40) : 40
Rectangle {
width: parent.width
height: maximumHeight != 0 ? Math.min(
minimumHeight != 0 ? Math.max(statusBaseInput.implicitHeight, minimumHeight)
: implicitHeight,
maximumHeight)
: parent.height
color: Theme.palette.baseColor2
radius: 8
clip: true
Flickable {
id: flick
anchors.fill: parent
anchors.leftMargin: statusBaseInput.leftPadding
anchors.rightMargin: statusBaseInput.rightPadding + clearable ? clearButtton.width : 0
anchors.topMargin: statusBaseInput.topPadding
anchors.bottomMargin: statusBaseInput.bottomPadding
contentWidth: edit.paintedWidth
contentHeight: edit.paintedHeight
clip: true
QC.ScrollBar.vertical: QC.ScrollBar { interactive: multiline }
function ensureVisible(r) {
if (contentX >= r.x)
contentX = r.x;
else if (contentX+width <= r.x+r.width)
contentX = r.x+r.width-width;
if (contentY >= r.y)
contentY = r.y;
else if (contentY+height <= r.y+r.height)
contentY = r.y+r.height-height;
}
TextEdit {
id: edit
width: flick.width
selectByMouse: true
anchors.verticalCenter: parent.verticalCenter
focus: true
font.pixelSize: 15
font.family: Theme.palette.baseFont.name
color: Theme.palette.directColor1
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
wrapMode: TextEdit.NoWrap
Keys.onReturnPressed: {
if (multiline) {
event.accepted = false
} else {
event.accepted = true
}
}
Keys.onEnterPressed: {
if (multiline) {
event.accepted = false
} else {
event.accepted = true
}
}
StatusBaseText {
id: placeholder
visible: edit.text.length === 0
anchors.left: parent.left
anchors.right: parent.right
font.pixelSize: 15
elide: StatusBaseText.ElideRight
font.family: Theme.palette.baseFont.name
color: Theme.palette.baseColor1
}
}
} // Flickable
MouseArea {
anchors.fill: parent
cursorShape: Qt.IBeamCursor
enabled: !edit.activeFocus
onClicked: edit.forceActiveFocus()
}
} // Rectangle
StatusFlatRoundButton {
id: clearButtton
visible: edit.text.length != 0 && statusBaseInput.clearable && !statusBaseInput.multiline
anchors.right: parent.right
anchors.rightMargin: 11
anchors.verticalCenter: parent.verticalCenter
type: StatusFlatRoundButton.Type.Secondary
width: 14
height: 14
icon.name: "clear"
icon.width: 14
icon.height: 14
onClicked: {
edit.clear()
}
}
}
+19 -8
View File
@@ -22,26 +22,30 @@ Rectangle {
property StatusIconSettings icon: StatusIconSettings {}
property int type: StatusChatInfoButton.Type.PublicChat
property alias tooltip: statusToolTip
property alias sensor: sensor
signal clicked(var mouse)
signal pinnedMessagesCountClicked(var mouse)
signal unmute()
enum Type {
PublicChat,
GroupChat,
CommunityChat,
OneToOneChat
Unknown0, // 0
OneToOneChat, // 1
PublicChat, // 2
GroupChat, // 3
Unknown1, // 4
Unknown2, // 5
CommunityChat // 6
}
radius: 8
color: sensor.containsMouse ? Theme.palette.baseColor2 : "transparent"
color: sensor.enabled && sensor.containsMouse ? Theme.palette.baseColor2 : "transparent"
MouseArea {
id: sensor
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: statusChatInfoButton.clicked(mouse)
@@ -69,6 +73,8 @@ Rectangle {
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
@@ -93,6 +99,7 @@ Rectangle {
Item {
id: statusChatInfoButtonTitle
anchors.top: identicon.top
anchors.topMargin: statusChatInfoButtonSubTitle.visible ? 0 : 8
anchors.left: identicon.right
anchors.leftMargin: 8
@@ -132,7 +139,10 @@ Rectangle {
anchors.leftMargin: statusIcon.visible ? 1 : 0
anchors.top: parent.top
text: statusChatInfoButton.title
text: statusChatInfoButton.type === StatusChatInfoButton.Type.PublicChat &&
!statusChatInfoButton.title.startsWith("#") ?
"#" + statusChatInfoButton.title :
statusChatInfoButton.title
color: statusChatInfoButton.muted ? Theme.palette.directColor5 : Theme.palette.directColor1
font.pixelSize: 15
font.weight: Font.Medium
@@ -171,7 +181,8 @@ Rectangle {
id: statusChatInfoButtonSubTitle
anchors.left: statusChatInfoButtonTitle.left
anchors.top: statusChatInfoButtonTitle.bottom
height: chatType.height
visible: !!statusChatInfoButton.subTitle
height: visible ? chatType.height : 0
width: childrenRect.width
StatusBaseText {
@@ -0,0 +1,59 @@
import QtQuick 2.14
import QtQuick.Controls 2.12
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Button {
id: root
implicitWidth: 446
implicitHeight: 44
property color bgColor: Theme.palette.baseColor2
property color contentColor: Theme.palette.baseColor1
signal clicked()
background: Item {
anchors.fill: parent
Rectangle {
id: background
anchors.fill: parent
radius: 8
color: root.bgColor
}
StatusIcon {
id: nextIcon
anchors.right: parent.right
anchors.rightMargin: 8
anchors.verticalCenter: parent.verticalCenter
icon: "next"
color: !Qt.colorEqual(root.contentColor, Theme.palette.baseColor1)
? root.contentColor : Theme.palette.directColor1
}
}
contentItem: Item {
anchors.fill: parent
StatusBaseText {
id: textLabel
anchors {
fill: parent
leftMargin: 16
}
verticalAlignment: Text.AlignVCenter
font.pixelSize: 15
color: root.contentColor
text: root.text
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.clicked();
}
}
}
+2
View File
@@ -14,3 +14,5 @@ StatusSwitch 0.1 StatusSwitch.qml
StatusRadioButton 0.1 StatusRadioButton.qml
StatusCheckBox 0.1 StatusCheckBox.qml
StatusSlider 0.1 StatusSlider.qml
StatusBaseInput 0.1 StatusBaseInput.qml
StatusPickerButton 0.1 StatusPickerButton.qml
+8 -7
View File
@@ -12,19 +12,20 @@ Image {
sourceSize.height: height
fillMode: Image.PreserveAspectFit
antialiasing: true
mipmap: true
onIconChanged: {
if (icon !== "") {
source = "../../assets/img/icons/" + icon + ".svg";
}
}
ColorOverlay {
visible: !Qt.colorEqual(statusIcon.color, "transparent")
anchors.fill: statusIcon
source: statusIcon
layer.mipmap: true
layer.smooth: true
layer.format: ShaderEffectSource.RGBA
layer.enabled:!Qt.colorEqual(statusIcon.color, "transparent")
layer.effect: ColorOverlay {
color: statusIcon.color
antialiasing: true
smooth: true
}
}
+1
View File
@@ -10,5 +10,6 @@ QtObject {
property color color
property url source
property int rotation
property bool isLetterIdenticon
property StatusIconBackgroundSettings background: StatusIconBackgroundSettings {}
}
+1
View File
@@ -6,5 +6,6 @@ QtObject {
property url source
property real width
property real height
property bool isIdenticon: false
}
@@ -0,0 +1,11 @@
import QtQuick 2.14
QtObject {
property string title
property string subTitle
property StatusImageSettings image: StatusImageSettings {
width: 40
height: 40
}
}
+1
View File
@@ -13,6 +13,7 @@ QtObject {
'blue3': '#88B0FF',
'blue4': '#869EFF',
'blue5': '#AAC6FF',
'blue6': '#ECEFFC',
'brown': '#8B3131',
'brown2': '#9B832F',
@@ -132,6 +132,7 @@ ThemePalette {
property QtObject statusListItem: QtObject {
property color backgroundColor: baseColor3
property color secondaryHoverBackgroundColor: primaryColor3
}
property QtObject statusChatListItem: QtObject {
@@ -163,5 +164,13 @@ ThemePalette {
property color hoverBackgroundColor: directColor7
property color separatorColor: directColor7
}
property QtObject statusModal: QtObject {
property color backgroundColor: baseColor3
}
property QtObject statusRoundedImage: QtObject {
property color backgroundColor: baseColor3
}
}
@@ -130,6 +130,7 @@ ThemePalette {
property QtObject statusListItem: QtObject {
property color backgroundColor: white
property color secondaryHoverBackgroundColor: getColor('blue6')
}
property QtObject statusChatListItem: QtObject {
@@ -161,5 +162,13 @@ ThemePalette {
property color hoverBackgroundColor: baseColor2
property color separatorColor: baseColor2
}
property QtObject statusModal: QtObject {
property color backgroundColor: white
}
property QtObject statusRoundedImage: QtObject {
property color backgroundColor: white
}
}
+10
View File
@@ -28,6 +28,7 @@ QtObject {
property color white: getColor('white')
property color dropShadow: getColor('black', 0.12)
property color backdropColor: getColor('black', 0.4)
property color baseColor1
property color baseColor2
@@ -91,6 +92,7 @@ QtObject {
property QtObject statusListItem: QtObject {
property color backgroundColor
property color secondaryHoverBackgroundColor
}
property QtObject statusChatListItem: QtObject {
@@ -124,6 +126,14 @@ QtObject {
property color separatorColor
}
property QtObject statusModal: QtObject {
property color backgroundColor
}
property QtObject statusRoundedImage: QtObject {
property color backgroundColor
}
function alphaColor(color, alpha) {
let actualColor = Qt.darker(color, 1)
actualColor.a = alpha
+1
View File
@@ -5,4 +5,5 @@ StatusIcon 0.1 StatusIcon.qml
StatusIconSettings 0.1 StatusIconSettings.qml
StatusIconBackgroundSettings 0.1 StatusIconBackgroundSettings.qml
StatusImageSettings 0.1 StatusImageSettings.qml
StatusModalHeaderSettings 0.1 StatusModalHeaderSettings.qml
@@ -4,6 +4,7 @@ import QtQuick.Controls 2.13
import StatusQ.Core.Theme 0.1
MenuSeparator {
height: visible && enabled ? implicitHeight : 0
contentItem: Rectangle {
implicitWidth: 176
implicitHeight: 1
+71
View File
@@ -0,0 +1,71 @@
import QtQuick 2.14
import QtQuick.Controls 2.14 as QC
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import "statusModal" as Spares
QC.Popup {
id: statusModal
property Component content
property alias headerActionButton: headerImpl.actionButton
property StatusModalHeaderSettings header: StatusModalHeaderSettings {}
property alias contentComponent: contentLoader.item
property alias rightButtons: footerImpl.rightButtons
property alias leftButtons: footerImpl.leftButtons
signal editButtonClicked()
parent: QC.Overlay.overlay
width: 480
height: contentItem.implicitHeight
margins: 0
padding: 0
modal: true
QC.Overlay.modal: Rectangle {
color: Theme.palette.backdropColor
}
background: Rectangle {
color: Theme.palette.statusModal.backgroundColor
radius: 8
}
contentItem: Column {
width: parent.width
Spares.StatusModalHeader {
id: headerImpl
width: 480
title: header.title
subTitle: header.subTitle
image: header.image
onEditButtonClicked: statusModal.editButtonClicked()
onClose: statusModal.close()
}
Loader {
id: contentLoader
active: true
anchors.horizontalCenter: parent.horizontalCenter
sourceComponent: statusModal.content
}
Spares.StatusModalFooter {
id: footerImpl
width: 480
}
}
}
+31
View File
@@ -0,0 +1,31 @@
import QtQuick 2.14
import StatusQ.Core.Theme 0.1
Column {
spacing: 0
property real topPadding: 0
property real bottomPadding: 0
width: 480
Item {
id: topPaddingItem
height: parent.topPadding
width: parent.width
}
Rectangle {
id: divider
color: Theme.palette.baseColor2
height: 1
width: parent.width
}
Item {
id: bottomPaddingItem
height: parent.bottomPadding
width: parent.width
}
}
+2
View File
@@ -3,3 +3,5 @@ module StatusQ.Popups
StatusMenuSeparator 0.1 StatusMenuSeparator.qml
StatusPopupMenu 0.1 StatusPopupMenu.qml
StatusMenuItem 0.1 StatusMenuItem.qml
StatusModal 0.1 StatusModal.qml
StatusModalDivider 0.1 StatusModalDivider.qml
@@ -0,0 +1,69 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
Row {
id: statusImageWithTitle
property alias title: headerTitle.text
property alias subTitle: headerSubTitle.text
property bool editable: false
signal editButtonClicked
property StatusImageSettings image: StatusImageSettings {
width: 40
height: 40
}
spacing: 8
StatusRoundedImage {
id: headerImage
anchors.verticalCenter: parent.verticalCenter
width: statusImageWithTitle.image.width
height: statusImageWithTitle.image.height
image.source: statusImageWithTitle.image.source
showLoadingIndicator: true
visible: !!statusImageWithTitle.image.source.toString()
}
Column {
id: textLayout
Row {
spacing: 4
StatusBaseText {
id: headerTitle
font.family: Theme.palette.baseFont.name
font.pixelSize: 17
font.bold: true
color: Theme.palette.directColor1
}
StatusFlatRoundButton {
id: editButton
visible: statusImageWithTitle.editable
anchors.bottom: headerTitle.bottom
anchors.bottomMargin: -1
height: 24
width: 24
type: StatusFlatRoundButton.Type.Secondary
icon.name: "pencil"
icon.color: Theme.palette.directColor1
icon.width: 12.5
icon.height: 12.5
onClicked: statusImageWithTitle.editButtonClicked()
}
}
StatusBaseText {
id: headerSubTitle
font.family: Theme.palette.baseFont.name
font.pixelSize: 15
color:Theme.palette.baseColor1
}
}
}
@@ -0,0 +1,69 @@
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
Rectangle {
id: statusModalFooter
property list<Item> leftButtons
property list<StatusBaseButton> rightButtons
radius: 8
color: Theme.palette.statusModal.backgroundColor
onLeftButtonsChanged: {
for (let idx in leftButtons) {
leftButtons[idx].parent = leftButtonsLayout
}
}
onRightButtonsChanged: {
for (let idx in rightButtons) {
rightButtons[idx].parent = rightButtonsLayout
}
}
implicitHeight: rootLayout.implicitHeight + 30
RowLayout {
id: rootLayout
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.rightMargin: 18
Row {
id: leftButtonsLayout
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
spacing: 16
}
Item {
Layout.fillWidth: true
implicitHeight: 1
}
Row {
id: rightButtonsLayout
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
spacing: 16
}
}
Rectangle {
anchors.top: parent.top
width: parent.width
height: parent.radius
color: parent.color
}
}
@@ -0,0 +1,70 @@
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
Rectangle {
id: statusModalHeader
property alias title: imageWithTitle.title
property alias subTitle: imageWithTitle.subTitle
property alias actionButton: actionButtonLoader.sourceComponent
property alias image: imageWithTitle.image
property bool editable: false
signal editButtonClicked
signal close
implicitHeight: Math.max(closeButton.height, imageWithTitle.implicitHeight) + 32
implicitWidth: 480
radius: 16
color: Theme.palette.statusModal.backgroundColor
StatusImageWithTitle {
id: imageWithTitle
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 16
editable: statusModalHeader.editable
onEditButtonClicked: statusModalHeader.editButtonClicked()
}
Loader {
id: actionButtonLoader
anchors.right: closeButton.left
anchors.rightMargin: 8
anchors.top: parent.top
anchors.topMargin: 16
}
StatusFlatRoundButton {
id: closeButton
anchors.right: parent.right
anchors.rightMargin: 20
anchors.top: parent.top
anchors.topMargin: 16
width: 32
height: 32
type: StatusFlatRoundButton.Type.Secondary
icon.name: "close"
icon.color: Theme.palette.directColor1
icon.width: 20
icon.height: 20
onClicked: statusModalHeader.close()
}
Rectangle {
anchors.bottom: parent.bottom
width: parent.width
height: parent.radius
color: parent.color
}
}
+4
View File
@@ -0,0 +1,4 @@
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.100954 12.5959L0.798362 9.80623C0.830588 9.67733 0.871226 9.55116 0.919852 9.42847C0.981714 9.27239 1.18145 9.24231 1.30017 9.36102L3.63897 11.6998C3.75769 11.8185 3.7276 12.0183 3.57152 12.0801C3.44883 12.1288 3.32266 12.1694 3.19376 12.2016L0.404123 12.899C0.221028 12.9448 0.0551798 12.779 0.100954 12.5959Z" fill="black"/>
<path d="M4.32312 10.2627C4.71364 10.6532 5.34681 10.6532 5.73733 10.2627L12.2928 3.7072C12.6833 3.31668 12.6833 2.68351 12.2928 2.29299L10.707 0.7072C10.3165 0.316676 9.68332 0.316675 9.29279 0.707199L2.73733 7.26266C2.34681 7.65318 2.34681 8.28635 2.73733 8.67687L4.32312 10.2627Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 741 B

+8
View File
@@ -16,10 +16,12 @@
<file>src/StatusQ/Popups/StatusPopupMenu.qml</file>
<file>src/StatusQ/Popups/StatusMenuSeparator.qml</file>
<file>src/StatusQ/Popups/StatusMenuItem.qml</file>
<file>src/StatusQ/Popups/StatusModalDivider.qml</file>
<file>src/StatusQ/Components/qmldir</file>
<file>src/StatusQ/Components/StatusChatListItem.qml</file>
<file>src/StatusQ/Components/StatusChatListAndCategories.qml</file>
<file>src/StatusQ/Components/StatusChatInfoToolBar.qml</file>
<file>src/StatusQ/Components/StatusContactRequestsIndicatorListItem.qml</file>
<file>src/StatusQ/Components/StatusNavigationListItem.qml</file>
<file>src/StatusQ/Components/StatusNavigationPanelHeadline.qml</file>
<file>src/StatusQ/Components/StatusChatToolBar.qml</file>
@@ -239,7 +241,13 @@
<file>src/assets/img/icons/activity.svg</file>
<file>src/StatusQ/Components/StatusChatListCategoryItem.qml</file>
<file>src/StatusQ/Components/StatusChatListCategory.qml</file>
<file>src/StatusQ/Controls/StatusBaseInput.qml</file>
<file>src/StatusQ/Controls/StatusChatListCategoryItemButton.qml</file>
<file>src/StatusQ/Components/StatusChatList.qml</file>
<file>src/StatusQ/Popups/statusModal/StatusImageWithTitle.qml</file>
<file>src/StatusQ/Popups/statusModal/StatusModalFooter.qml</file>
<file>src/StatusQ/Popups/statusModal/StatusModalHeader.qml</file>
<file>src/StatusQ/Popups/StatusModal.qml</file>
<file>src/StatusQ/Core/StatusModalHeaderSettings.qml</file>
</qresource>
</RCC>