Compare commits

..
Author SHA1 Message Date
Igor Sirotin 45d7d80755 fix(StatusPopupMenu): Removed custom properties 2022-08-10 15:02:14 +03:00
140 changed files with 2391 additions and 26421 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

+4 -4
View File
@@ -63,7 +63,7 @@ Rectangle {
visible: titleStyle === "windows"
}
StatusMainLayout {
StatusAppLayout {
id: statusAppLayout
anchors.top: windowsTitle.visible ? windowsTitle.bottom : demoApp.top
anchors.left: demoApp.left
@@ -73,7 +73,7 @@ Rectangle {
height: demoApp.height - demoApp.border.width * 2
width: demoApp.width - demoApp.border.width * 2
leftPanel: StatusAppNavBar {
appNavBar: StatusAppNavBar {
id: navBar
@@ -181,7 +181,7 @@ Rectangle {
}
}
rightPanel: Loader {
appView: Loader {
id: appView
anchors.fill: parent
sourceComponent: statusAppChatView
@@ -197,7 +197,7 @@ Rectangle {
id: statusAppCommunityView
StatusAppCommunityView {
communityDetailModalTitle: demoCommunityDetailModal.header.title
communityDetailModalImage: demoCommunityDetailModal.header.asset.name
communityDetailModalImage: demoCommunityDetailModal.header.image.source
onChatInfoButtonClicked: {
demoCommunityDetailModal.open();
}
+2 -48
View File
@@ -21,37 +21,18 @@ Column {
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Primary
StatusToolTip {
visible: parent.hovered
text: "Look I'm a tooltip on a button!"
}
onClicked: console.warn("Primary button clicked")
onPressed: console.warn("Primary button pressed")
}
StatusButton {
text: "Button"
enabled: false
type: StatusBaseButton.Type.Primary
StatusToolTip {
visible: parent.hovered
text: "Tooltip on a disabled button, should not be visible!"
}
onClicked: console.warn("Primary disabled button clicked, this should not happen !!!")
}
StatusButton {
text: "Button"
loading: true
type: StatusBaseButton.Type.Primary
StatusToolTip {
visible: parent.hovered
text: "Look I'm a tooltip on a loading button!"
}
onClicked: console.warn("Primary loading button clicked, this should not happen !!!")
}
// Large
@@ -69,25 +50,6 @@ Column {
loading: true
}
// Large + Icon
StatusButton {
text: "Button"
icon.name: "info"
}
StatusButton {
text: "Button"
enabled: false
icon.name: "info"
}
StatusButton {
text: "Button"
loading: true
icon.name: "info"
}
// Danger
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Danger
@@ -105,7 +67,6 @@ Column {
type: StatusBaseButton.Type.Danger
}
// Flat
StatusFlatButton {
text: "Button"
}
@@ -113,6 +74,7 @@ Column {
StatusFlatButton {
text: "Button"
enabled: false
}
StatusFlatButton {
@@ -120,7 +82,6 @@ Column {
loading: true
}
// Flat + Danger
StatusFlatButton {
text: "Button"
type: StatusBaseButton.Type.Danger
@@ -156,7 +117,6 @@ Column {
loading: true
}
// Small + danger
StatusButton {
text: "Button"
type: StatusBaseButton.Type.Danger
@@ -177,7 +137,6 @@ Column {
loading: true
}
// Flat + small
StatusFlatButton {
text: "Button"
size: StatusBaseButton.Size.Small
@@ -400,12 +359,7 @@ Column {
// Button with emoji
StatusButton {
text: "Button with Emoji"
asset.emoji: "🖼️"
}
StatusButton {
width: parent.width
text: "wide"
icon.emoji: "🖼️"
}
RowLayout {
+12 -37
View File
@@ -113,33 +113,18 @@ GridLayout {
StatusSwitch {
}
StatusSwitch {
text: "Switch with text"
}
StatusRadioButton {
text: "Radio button 1"
checked: true
}
StatusRadioButton {
text: "Radio button 2 (clicking on this text will uncheck the above)"
}
StatusRadioButton {
LayoutMirroring.enabled : true
text: "Radio button 3 (forced right-to-left)"
text: "i'm radio!"
}
StatusCheckBox {}
StatusCheckBox { checkState: Qt.Checked}
StatusCheckBox { text: "Check me on left side"}
StatusCheckBox { text: "Check me on right side"; leftSide: false}
StatusChatInfoButton {
title: "Iuri Matias"
subTitle: "Contact"
asset.color: Theme.palette.miscColor7
asset.isImage: true
asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
icon.color: Theme.palette.miscColor7
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
type: StatusChatInfoButton.Type.OneToOneChat
muted: true
pinnedMessagesCount: 1
@@ -150,13 +135,12 @@ GridLayout {
implicitHeight: 48
StatusChatInfoButton {
title: "Iuri Matias elided"
subTitle: "Very long subtitle should elide as well"
asset.color: Theme.palette.miscColor7
asset.isImage: true
asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
subTitle: "Contact"
icon.color: Theme.palette.miscColor7
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
type: StatusChatInfoButton.Type.OneToOneChat
muted: true
pinnedMessagesCount: 10
pinnedMessagesCount: 1
width: 100
}
}
@@ -167,9 +151,8 @@ GridLayout {
StatusChatInfoButton {
title: "Iuri Matias big not elided"
subTitle: "Contact"
asset.color: Theme.palette.miscColor7
asset.isImage: true
asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
icon.color: Theme.palette.miscColor7
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
type: StatusChatInfoButton.Type.OneToOneChat
muted: true
pinnedMessagesCount: 1
@@ -181,32 +164,24 @@ GridLayout {
title: "group"
subTitle: "Group Chat"
pinnedMessagesCount: 1
asset.color: Theme.palette.miscColor7
icon.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.GroupChat
}
StatusChatInfoButton {
title: "public-chat"
subTitle: "Public Chat"
asset.color: Theme.palette.miscColor7
icon.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.PublicChat
}
StatusChatInfoButton {
title: "community-channel"
subTitle: "Community Chat"
asset.color: Theme.palette.miscColor7
icon.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.CommunityChat
}
StatusChatInfoButton {
title: "community-channel"
subTitle: "Some very long description text to see how the whole item wraps or elides"
asset.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.CommunityChat
pinnedMessagesCount: 3
}
StatusSlider {
width: 360
from: 0
+69 -67
View File
@@ -12,94 +12,93 @@ import StatusQ.Popups 0.1
Column {
spacing: 10
StatusToolBar {
StatusChatToolBar {
toolbarComponent: chatInfoButton1
width: 518
headerContent: StatusChatInfoButton {
width: Math.min(implicitWidth, parent.width)
title: "Some contact"
subTitle: "Contact"
asset.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.OneToOneChat
Component {
id: chatInfoButton1
StatusChatInfoButton {
width: Math.min(implicitWidth, parent.width)
title: "Some contact"
subTitle: "Contact"
icon.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.OneToOneChat
}
}
}
StatusToolBar {
StatusChatToolBar {
toolbarComponent: chatInfoButton2
width: 518
headerContent: StatusChatInfoButton {
width: Math.min(implicitWidth, parent.width)
title: "Muted public chat"
subTitle: "Some subtitle"
asset.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.PublicChat
pinnedMessagesCount: 1
muted: true
Component {
id: chatInfoButton2
StatusChatInfoButton {
width: Math.min(implicitWidth, parent.width)
title: "Some contact"
subTitle: "Contact"
icon.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.PublicChat
pinnedMessagesCount: 1
muted: true
}
}
}
StatusToolBar {
StatusChatToolBar {
notificationCount: 1
toolbarComponent: chatInfoButton3
width: 518
headerContent: StatusChatInfoButton {
width: Math.min(implicitWidth, parent.width)
title: "Group chat"
subTitle: "Group chat subtitle"
asset.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.GroupChat
pinnedMessagesCount: 1
Component {
id: chatInfoButton3
StatusChatInfoButton {
width: Math.min(implicitWidth, parent.width)
title: "Some contact"
subTitle: "Contact"
icon.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.OneToOneChat
pinnedMessagesCount: 1
}
}
}
StatusToolBar {
width: 518
headerContent: StatusChatInfoButton {
title: "Community chat"
subTitle: "Some very long description text to see how the whole item wraps or ellides"
asset.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.CommunityChat
pinnedMessagesCount: 3
}
}
StatusToolBar {
headerContent: StatusChatInfoButton {
title: "Very long chat name"
asset.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.CommunityChat
pinnedMessagesCount: 1234567891
}
}
StatusToolBar {
StatusChatToolBar {
notificationCount: 1
toolbarComponent: tagSelector
width: 518
StatusTagSelector {
namesModel: ListModel {
ListElement {
publicId: "0x0"
name: "Maria"
icon: ""
isIdenticon: false
onlineStatus: 3
isReadonly: true
tagIcon: "crown"
}
ListElement {
publicId: "0x1"
name: "James"
icon: ""
isIdenticon: false
onlineStatus: 1
isReadonly: false
tagIcon: ""
Component {
id: tagSelector
StatusTagSelector {
namesModel: ListModel {
ListElement {
publicId: "0x0"
name: "Maria"
icon: ""
isIdenticon: false
onlineStatus: 3
isReadonly: true
tagIcon: "crown"
}
ListElement {
publicId: "0x1"
name: "James"
icon: ""
isIdenticon: false
onlineStatus: 1
isReadonly: false
tagIcon: ""
}
}
toLabelText: qsTr("To: ")
warningText: qsTr("USER LIMIT REACHED")
}
toLabelText: qsTr("To: ")
warningText: qsTr("USER LIMIT REACHED")
}
}
@@ -494,5 +493,8 @@ Column {
}
}
}
}
}
+62 -202
View File
@@ -1,6 +1,4 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQml.Models 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
@@ -8,8 +6,10 @@ import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Utils 0.1
ColumnLayout {
spacing: 5
GridLayout {
columns: 1
columnSpacing: 5
rowSpacing: 5
StatusNavigationListItem {
title: "Menu Item"
@@ -17,18 +17,18 @@ ColumnLayout {
StatusNavigationListItem {
title: "Menu Item"
asset.name: "info"
icon.name: "info"
}
StatusNavigationListItem {
title: "Menu Item"
asset.name: "info"
icon.name: "info"
badge.value: 1
}
StatusNavigationListItem {
title: "Menu Item (selected) with very long text"
selected: true
asset.name: "info"
icon.name: "info"
badge.value: 1
}
@@ -55,59 +55,6 @@ ColumnLayout {
opened: true
}
StatusChatListCategoryItem {
id: categoryItemInteractive
title: "Chat category interactive"
showActionButtons: true
onAddButtonClicked: testEventsList.eventTriggered("Add button clicked")
onMenuButtonClicked: testEventsList.eventTriggered("Menu button clicked")
onToggleButtonClicked: {
opened = !opened
testEventsList.eventTriggered("Toggle button clicked")
}
onTitleClicked: {
testEventsList.eventTriggered("Title clicked")
}
onClicked: {
opened = !opened
testEventsList.eventTriggered("Item clicked", itemId)
}
}
ListView {
id: testEventsList
Layout.fillWidth: true
Layout.preferredHeight: categoryItemInteractive.opened ? 20 * count : 0
clip: true
function eventTriggered(message) {
let obj = eventDelegateComponent.createObject()
obj.text = message
model.insert(0, obj)
}
Component {
id: eventDelegateComponent
ItemDelegate {
implicitHeight: 20
property int index: ObjectModel.index
Timer {
interval: 5000; running: true
onTriggered: testObjectModel.remove(index)
}
}
}
model: ObjectModel {
id: testObjectModel
}
}
StatusChatListItem {
name: "group-chat"
type: StatusChatListItem.Type.GroupChat
@@ -121,20 +68,18 @@ ColumnLayout {
StatusChatListItem {
name: "community-channel-emoji"
type: StatusChatListItem.Type.CommunityChat
asset.emoji: "😁"
icon.emoji: "😁"
}
StatusChatListItem {
name: "community-channel-with-image"
asset.isImage: true
asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
type: StatusChatListItem.Type.CommunityChat
}
StatusChatListItem {
name: "Weird Crazy Otter"
asset.isImage: true
asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
type: StatusChatListItem.Type.OneToOneChat
}
@@ -219,7 +164,7 @@ ColumnLayout {
title: "Title"
subTitle: "Super long description that causes a multiline paragraph and makes the size of the component grow. Let's see how it behaves."
tertiaryTitle: "Tertiary title"
asset.name: "info"
icon.name: "info"
statusListItemTitle.font.pixelSize: 17
statusListItemTitle.font.weight: Font.Bold
@@ -228,29 +173,27 @@ ColumnLayout {
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.name: "info"
icon.name: "info"
}
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.isImage: true
asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
}
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.isImage: true
asset.name: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
asset.imgIsIdenticon: true
image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
image.isIdenticon: true
}
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.name: "info"
icon.name: "info"
components: [StatusButton {
text: "Button"
size: StatusBaseButton.Size.Small
@@ -260,35 +203,35 @@ ColumnLayout {
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.name: "info"
icon.name: "info"
components: [StatusSwitch {}]
}
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.name: "info"
icon.name: "info"
components: [StatusRadioButton {}]
}
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.name: "info"
icon.name: "info"
components: [StatusCheckBox {}]
}
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.name: "info"
icon.name: "info"
label: "Text"
}
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.name: "info"
icon.name: "info"
label: "Text"
components: [
StatusButton {
@@ -301,7 +244,7 @@ ColumnLayout {
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.name: "info"
icon.name: "info"
label: "Text"
components: [StatusSwitch {}]
}
@@ -309,7 +252,7 @@ ColumnLayout {
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.name: "info"
icon.name: "info"
label: "Text"
components: [
StatusRadioButton {}
@@ -319,7 +262,7 @@ ColumnLayout {
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.name: "info"
icon.name: "info"
label: "Text"
components: [StatusCheckBox {}]
}
@@ -327,7 +270,7 @@ ColumnLayout {
StatusListItem {
title: "Title"
subTitle: "Subtitle"
asset.name: "info"
icon.name: "info"
label: "Text"
components: [
StatusBadge {
@@ -344,14 +287,14 @@ ColumnLayout {
StatusListItem {
title: "Title"
asset.name: "info"
icon.name: "info"
type: StatusListItem.Type.Secondary
}
StatusListItem {
title: "Title"
asset.isLetterIdenticon: true
asset.color: "orange"
icon.isLetterIdenticon: true
icon.color: "orange"
}
StatusListItem {
@@ -361,19 +304,17 @@ ColumnLayout {
StatusListItem {
title: "Title"
asset.name: "delete"
icon.name: "delete"
type: StatusListItem.Type.Danger
}
StatusListItem {
title: "List Item with Badge"
subTitle: "Subtitle"
asset.isImage: true
asset.name: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
asset.imgIsIdenticon: true
badge.asset.isImage: true
badge.asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
image.isIdenticon: true
badge.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
badge.primaryText: "CryptoKitties"
badge.secondaryText: "#test"
}
@@ -381,57 +322,36 @@ ColumnLayout {
StatusListItem {
title: "List Item with Badge 2"
subTitle: "Subtitle"
asset.isLetterIdenticon: true
icon.isLetterIdenticon: true
badge.primaryText: "CryptoKitties"
badge.secondaryText: "#test"
badge.asset.color: "orange"
badge.asset.isLetterIdenticon: true
badge.icon.color: "orange"
badge.icon.isLetterIdenticon: true
}
StatusListItem {
title: "List Item with Tags"
asset.isLetterIdenticon: true
icon.isLetterIdenticon: true
bottomModel: 3
bottomDelegate: StatusListItemTag {
title: "tag"
asset.isLetterIdenticon: true
icon.isLetterIdenticon: true
}
}
StatusListItem {
title: "List Item with Inline Tags"
asset.isLetterIdenticon: true
tagsModel: ListModel{
ListElement {
name: "helloworld.eth"
emoji: "😁"
}
ListElement {
name: "account1"
emoji: "😁"
}
ListElement {
name: "account2"
emoji: "😁"
}
ListElement {
name: "account3"
emoji: "😁"
}
ListElement {
name: "account4"
emoji: "😁"
}
}
icon.isLetterIdenticon: true
tagsModel : 2
tagsDelegate: StatusListItemTag {
color: "blue"
height: 24
radius: 6
closeButtonVisible: false
asset.emoji: model.emoji
asset.emojiSize: Emoji.size.verySmall
asset.isLetterIdenticon: true
title: model.name
icon.emoji: "😁"
icon.emojiSize: Emoji.size.verySmall
icon.isLetterIdenticon: true
title: "helloworld.eth"
titleText.font.pixelSize: 12
titleText.color: Theme.palette.indirectColor1
}
@@ -440,10 +360,10 @@ ColumnLayout {
StatusListItem {
title: "List Item with Emoji"
subTitle: "Emoji"
asset.emoji: "😁"
asset.color: "yellow"
asset.letterSize: 14
asset.isLetterIdenticon: true
icon.emoji: "😁"
icon.color: "yellow"
icon.letterSize: 14
icon.isLetterIdenticon: true
}
StatusDescriptionListItem {
@@ -462,7 +382,7 @@ ColumnLayout {
title: "Title"
subTitle: "Subtitle"
tooltip.text: "Tooltip"
asset.name: "info"
icon.name: "info"
iconButton.onClicked: tooltip.visible = !tooltip.visible
}
@@ -477,10 +397,9 @@ ColumnLayout {
pubKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
isVerified: true
isContact: true
asset.isImage: true
asset.name: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
asset.imgIsIdenticon: true
image.isIdenticon: true
status: 1 // FIXME: use enum
ringSettings.ringSpecModel:
ListModel {
@@ -498,27 +417,16 @@ ColumnLayout {
StatusMemberListItem {
nickName: "carmen.eth"
isUntrustworthy: true
asset.isLetterIdenticon: true
}
StatusMemberListItem {
nickName: "very-long-annoying-nickname.eth"
isUntrustworthy: true
asset.isLetterIdenticon: true
}
StatusMemberListItem {
nickName: "untrusted-admin.eth"
asset.isLetterIdenticon: true
isUntrustworthy: true
isAdmin: true
isContact: true
}
StatusMemberListItem {
nickName: "This girl I know from work"
userName: "annabelle"
asset.isLetterIdenticon: true
status: 1 // FIXME: use enum
}
@@ -527,21 +435,15 @@ ColumnLayout {
userName: "annabelle"
pubKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
isContact: true
asset.isImage: true
asset.name: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
asset.imgIsIdenticon: true
image.isIdenticon: true
}
StatusMemberListItem {
nickName: "admin.guy"
userName: "adguy"
isAdmin: true
asset.isLetterIdenticon: true
isUntrustworthy: true
Component.onCompleted: {
print(asset.name, asset.isImage, asset.isLetterIdenticon)
}
}
StatusBaseText {
@@ -555,12 +457,10 @@ ColumnLayout {
title: "Nokia 3310"
subTitle: "Incoming device"
label: "loading: true"
asset.width: 40
asset.height: 40
asset.emoji: "😁"
asset.color: "hotpink"
asset.letterSize: 14
asset.isLetterIdenticon: true
icon.emoji: "😁"
icon.color: "hotpink"
icon.letterSize: 14
icon.isLetterIdenticon: true
loading: true
}
@@ -568,50 +468,10 @@ ColumnLayout {
title: "Nokia 3310"
subTitle: "Device"
label: "loadingFailed: true"
asset.width: 40
asset.height: 40
asset.emoji: "😁"
asset.color: "hotpink"
asset.letterSize: 14
asset.isLetterIdenticon: true
icon.emoji: "😁"
icon.color: "hotpink"
icon.letterSize: 14
icon.isLetterIdenticon: true
loadingFailed: true
}
StatusListItem {
implicitWidth: 600
title: "List Item with Tags"
subTitle: "03:32"
asset.isLetterIdenticon: true
inlineTagModel: 6
inlineTagDelegate: StatusListItemTag {
height: 24
title: "tag"
asset.isLetterIdenticon: true
}
components: [
ColumnLayout {
Row {
Layout.alignment: Qt.AlignRight
spacing: 4
StatusIcon {
color: Theme.palette.successColor1
icon: "arrow-up"
rotation: 135
height: 18
}
StatusBaseText {
text: "0.0000015 ETH"
font.pixelSize: 15
color: Theme.palette.directColor1
}
}
StatusBaseText {
Layout.alignment: Qt.AlignRight
text: "1201.10 USD"
font.pixelSize: 15
color: Theme.palette.baseColor1
}
}
]
}
}
+1 -1
View File
@@ -40,7 +40,7 @@ ColumnLayout {
}
StatusRoundIcon {
asset.name: "info"
icon.name: "info"
}
}
+20 -24
View File
@@ -109,8 +109,7 @@ Column {
anchors.centerIn: parent
header.title: "Some Title"
header.subTitle: "Subtitle"
header.asset.isImage: true
header.asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
header.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
}
StatusModal {
@@ -118,8 +117,7 @@ Column {
anchors.centerIn: parent
header.title: "Some Title"
header.subTitle: "Subtitle"
header.asset.isImage: true
header.asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
header.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
leftButtons: [
StatusBackButton { }
]
@@ -138,8 +136,7 @@ Column {
anchors.centerIn: parent
header.title: "Some Title"
header.subTitle: "Subtitle"
header.asset.isImage: true
header.asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
header.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
headerActionButton: StatusFlatRoundButton {
type: StatusFlatRoundButton.Type.Secondary
@@ -167,8 +164,7 @@ Column {
StatusModal {
id: modalExample
anchors.centerIn: parent
header.asset.isImage: true
header.asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
header.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
header.title: "Header"
header.subTitle: "SubTitle"
rightButtons: [
@@ -231,8 +227,8 @@ Column {
anchors.centerIn: parent
header.title: "Header"
header.subTitle: "SubTitle"
header.asset.isLetterIdenticon: true
header.asset.bgColor: "red"
header.icon.isLetterIdenticon: true
header.icon.background.color: "red"
contentItem: StatusBaseText {
anchors.centerIn: parent
@@ -256,9 +252,9 @@ Column {
anchors.centerIn: parent
header.title: "Header"
header.subTitle: "SubTitle"
header.asset.name: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
header.asset.imgIsIdenticon: true
header.image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
header.image.isIdenticon: true
contentItem: StatusBaseText {
anchors.centerIn: parent
@@ -283,9 +279,9 @@ Column {
header.title: "Header"
header.subTitle: "SubTitle"
header.headerImageEditable: true
header.asset.name: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
header.asset.imgIsIdenticon: true
header.image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
header.image.isIdenticon: true
contentItem: StatusBaseText {
anchors.centerIn: parent
@@ -310,9 +306,9 @@ Column {
header.title: "Some super long text here that exceeds the available space"
header.subTitle: "Some super long text here that exceeds the available space"
header.subTitleElide: Text.ElideMiddle
header.asset.name: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
header.asset.imgIsIdenticon: true
header.image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
header.image.isIdenticon: true
contentItem: StatusBaseText {
anchors.centerIn: parent
@@ -344,7 +340,7 @@ Column {
sourceComponent: popupMenu.delegate
onLoaded: {
item.action.text = model.name
item.action.assetSettings.name = model.iconName
item.action.iconSettings.name = model.iconName
}
}
}
@@ -419,11 +415,11 @@ Column {
topPadding: 8
bottomPadding: 0
implicitHeight: 32
leftPadding: 4
defaultLeftPadding: 4
text: name
asset.emoji: !!emoji ? emoji: ""
asset.emojiSize: Emoji.size.middle
asset.name: !emoji ? "filled-account": ""
icon.emoji: !!emoji ? emoji: ""
icon.emojiSize: Emoji.size.middle
icon.name: !emoji ? "filled-account": ""
normalColor: "transparent"
highlighted: index === floatingHeader.currentIndex
onClicked: {
+22 -48
View File
@@ -14,10 +14,9 @@ ListView {
anchors.fill: parent
anchors.margins: 15
clip: true
delegate: StatusMessage {
id: delegate
width: ListView.view.width
width: parent.width
audioMessageInfoText: "Audio Message"
cancelButtonText: "Cancel"
@@ -27,69 +26,44 @@ ListView {
resendText: "Resend"
pinnedMsgInfoText: "Pinned by"
timestamp: model.timestamp
isAReply: model.isReply
hasMention: model.hasMention
isPinned: model.isPinned
pinnedBy: model.pinnedBy
hasExpired: model.hasExpired
reactionsModel: model.reactions || []
messageDetails: StatusMessageDetails {
contentType: model.contentType
messageContent: model.messageContent
amISender: model.amIsender
sender.id: model.senderId
sender.displayName: model.senderDisplayName
sender.secondaryName: model.senderOptionalName
sender.isContact: model.isContact
sender.trustIndicator: model.trustIndicator
sender.profileImage: StatusProfileImageSettings {
displayName: model.userName
secondaryName: model.localName !== "" && model.ensName.startsWith("@") ? model.ensName: ""
chatID: model.chatKey
profileImage: StatusImageSettings {
width: 40
height: 40
pubkey: model.senderId
name: model.profileImage || ""
colorId: 1
colorHash: ListModel {
ListElement { colorId: 13; segmentLength: 5 }
ListElement { colorId: 31; segmentLength: 5 }
ListElement { colorId: 10; segmentLength: 1 }
ListElement { colorId: 2; segmentLength: 5 }
ListElement { colorId: 26; segmentLength: 2 }
ListElement { colorId: 19; segmentLength: 4 }
ListElement { colorId: 28; segmentLength: 3 }
}
source: model.profileImage
isIdenticon: model.isIdenticon
}
messageText: model.message
hasMention: model.hasMention
isContact: model.isContact
trustIndicator: model.trustIndicator
isPinned: model.isPinned
pinnedBy: model.pinnedBy
hasExpired: model.hasExpired
}
timestamp.text: "10:00 am"
timestamp.tooltip.text: "10:01 am"
// reply related data
isAReply: model.isReply
replyDetails: StatusMessageDetails {
amISender: model.isReply && model.replyAmISender
sender.id: model.replySenderId || ""
sender.displayName: model.isReply ? model.replySenderName: ""
sender.secondaryName: model.isReply ? model.replySenderEnsName : ""
sender.profileImage: StatusProfileImageSettings {
amISender: model.isReply ? model.replyAmISender : ""
displayName: model.isReply ? model.replySenderName: ""
profileImage: StatusImageSettings {
width: 20
height: 20
name: model.isReply ? model.replyProfileImage: ""
pubkey: model.replySenderId
colorId: 1
colorHash: ListModel {
ListElement { colorId: 13; segmentLength: 5 }
ListElement { colorId: 31; segmentLength: 5 }
ListElement { colorId: 10; segmentLength: 1 }
ListElement { colorId: 2; segmentLength: 5 }
ListElement { colorId: 26; segmentLength: 2 }
ListElement { colorId: 19; segmentLength: 4 }
ListElement { colorId: 28; segmentLength: 3 }
}
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
+4 -3
View File
@@ -98,15 +98,16 @@ Page {
anchors.fill: parent
StatusBaseText {
width: Math.min(553, parent.width - 32)
anchors.horizontalCenter: parent.horizontalCenter
anchors.left: parent.left
anchors.leftMargin: 252
anchors.right: parent.right
anchors.rightMargin: 252
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -(headerRow.height/2)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
visible: contactsModel.count === 0
wrapMode: Text.WordWrap
font.pixelSize: 15
color: Theme.palette.baseColor1
text: qsTr("You can only send direct messages to your Contacts.\n
Send a contact request to the person you would like to chat with, you will be able to chat with them once they have accepted your contact request.")
+7 -8
View File
@@ -13,8 +13,7 @@ StatusModal {
header.title: "Cryptokitties"
header.subTitle: "Public Community"
header.asset.isImage: true
header.asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
header.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
contentItem: Column {
width: root.width
@@ -44,7 +43,7 @@ StatusModal {
title: "Share community"
subTitle: "https://join.status.im/u/0x04...45f19"
tooltip.text: "Copy to clipboard"
asset.name: "copy"
icon.name: "copy"
iconButton.onClicked: tooltip.visible = !tooltip.visible
width: parent.width
}
@@ -58,7 +57,7 @@ StatusModal {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Members"
asset.name: "group-chat"
icon.name: "group-chat"
label: "184"
components: [
StatusIcon {
@@ -73,7 +72,7 @@ StatusModal {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Notifications"
asset.name: "notification"
icon.name: "notification"
components: [
StatusSwitch {}
]
@@ -88,7 +87,7 @@ StatusModal {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Edit community"
asset.name: "edit"
icon.name: "edit"
type: StatusListItem.Type.Secondary
}
@@ -96,7 +95,7 @@ StatusModal {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Transfer ownership"
asset.name: "exchange"
icon.name: "exchange"
type: StatusListItem.Type.Secondary
}
@@ -104,7 +103,7 @@ StatusModal {
anchors.horizontalCenter: parent.horizontalCenter
statusListItemTitle.font.pixelSize: 17
title: "Leave community"
asset.name: "arrow-left"
icon.name: "arrow-left"
type: StatusListItem.Type.Secondary
}
}
+55 -106
View File
@@ -10,113 +10,10 @@ import StatusQ.Core.Theme 0.1
import "data" 1.0
StatusSectionLayout {
StatusAppThreePanelLayout {
id: root
property bool createChat: false
notificationCount: 1
onNotificationButtonClicked: { notificationCount = 0; }
showHeader: !root.createChat
headerContent: RowLayout {
id: chatHeader
signal chatInfoButtonClicked()
signal menuButtonClicked()
signal membersButtonClicked()
signal searchButtonClicked()
StatusChatInfoButton {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignLeft
Layout.leftMargin: padding
title: "Amazing Funny Squirrel"
subTitle: "Contact"
asset.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.OneToOneChat
pinnedMessagesCount: 1
}
RowLayout {
id: actionButtons
Layout.alignment: Qt.AlignRight
Layout.rightMargin: padding
spacing: 8
StatusFlatRoundButton {
id: menuButton
objectName: "chatToolbarMoreOptionsButton"
width: 32
height: 32
icon.name: "more"
type: StatusFlatRoundButton.Type.Secondary
// initializing the tooltip
tooltip.visible: !!tooltip.text && menuButton.hovered && !contextMenu.open
tooltip.text: qsTr("More")
tooltip.orientation: StatusToolTip.Orientation.Bottom
tooltip.y: parent.height + 12
property bool showMoreMenu: false
onClicked: {
menuButton.highlighted = true
let originalOpenHandler = contextMenu.openHandler
let originalCloseHandler = contextMenu.closeHandler
contextMenu.openHandler = function () {
if (!!originalOpenHandler) {
originalOpenHandler()
}
}
contextMenu.closeHandler = function () {
menuButton.highlighted = false
if (!!originalCloseHandler) {
originalCloseHandler()
}
}
contextMenu.openHandler = originalOpenHandler
contextMenu.popup(-contextMenu.width + menuButton.width, menuButton.height + 4)
}
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-left"
type: StatusMenuItem.Type.Danger
}
}
}
Rectangle {
width: 1
height: 24
color: Theme.palette.directColor7
Layout.alignment: Qt.AlignVCenter
visible: (notificationButton.visible && menuButton.visible)
}
}
}
leftPanel: Item {
anchors.fill: parent
anchors.margins: 16
@@ -179,7 +76,7 @@ StatusSectionLayout {
topPadding: 8
bottomPadding: 8
placeholderText: "Search"
input.asset.name: "search"
input.icon.name: "search"
}
Column {
@@ -194,7 +91,7 @@ StatusSectionLayout {
anchors.horizontalCenter: parent.horizontalCenter
title: "Contact requests"
requestsCount: 3
onClicked: demoContactRequestsModal.open()
sensor.onClicked: demoContactRequestsModal.open()
}
StatusChatList {
@@ -269,4 +166,56 @@ StatusSectionLayout {
}
}
}
rightPanel: Item {
anchors.fill: parent
StatusChatToolBar {
width: parent.width
toolbarComponent: statusChatInfoButton
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-left"
type: StatusMenuItem.Type.Danger
}
}
Component {
id: statusChatInfoButton
StatusChatInfoButton {
width: Math.min(implicitWidth, parent.width)
title: "Amazing Funny Squirrel"
subTitle: "Contact"
icon.color: Theme.palette.miscColor7
type: StatusChatInfoButton.Type.OneToOneChat
pinnedMessagesCount: 1
}
}
}
}
}
+109 -114
View File
@@ -5,12 +5,12 @@ import QtQuick.Layouts 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Layout 0.1
import StatusQ.Components 0.1
import "../demoapp/data" 1.0
StatusSectionLayout {
StatusScrollView {
id: root
QtObject {
@@ -31,129 +31,124 @@ StatusSectionLayout {
console.info("Clicked community ID: " + communityId)
}
}
centerPanel: Item {
anchors.fill: parent
clip: true
StatusScrollView {
anchors.fill: parent
contentHeight: column.height + d.layoutVMargin
contentWidth: column.width + d.layoutHMargin
ColumnLayout {
id: column
spacing: 18
contentHeight: column.height + d.layoutVMargin
contentWidth: column.width + d.layoutHMargin
clip: true
StatusBaseText {
Layout.topMargin: d.layoutVMargin
Layout.leftMargin: d.layoutHMargin
text: qsTr("Find community")
font.weight: Font.Bold
font.pixelSize: d.titlePixelSize
color: Theme.palette.directColor1
ColumnLayout {
id: column
spacing: 18
StatusBaseText {
Layout.topMargin: d.layoutVMargin
Layout.leftMargin: d.layoutHMargin
text: qsTr("Find community")
font.weight: Font.Bold
font.pixelSize: d.titlePixelSize
color: Theme.palette.directColor1
}
// Tags definition - Now hidden - Out of scope
// TODO: Replace by `StatusListItemTagRow`
Row {
visible: d.tagsModel.count > 0
Layout.leftMargin: d.layoutHMargin
Layout.rightMargin: d.layoutHMargin
width: 1234 // by design
spacing: d.stylePadding/2
Repeater {
model: d.tagsModel
delegate: StatusListItemTag {
border.color: Theme.palette.baseColor2
color: "transparent"
height: 32
radius: 36
closeButtonVisible: false
icon.emoji: model.emoji
icon.height: 32
icon.width: icon.height
icon.color: "transparent"
icon.isLetterIdenticon: true
title: model.name
titleText.font.pixelSize: 15
titleText.color: Theme.palette.primaryColor1
}
}
}
// Tags definition - Now hidden - Out of scope
// TODO: Replace by `StatusListItemTagRow`
Row {
visible: d.tagsModel.count > 0
Layout.leftMargin: d.layoutHMargin
Layout.rightMargin: d.layoutHMargin
width: 1234 // by design
spacing: d.stylePadding/2
StatusBaseText {
Layout.leftMargin: d.layoutHMargin
Layout.topMargin: 20
text: qsTr("Featured")
font.weight: Font.Bold
font.pixelSize: d.subtitlePixelSize
color: Theme.palette.directColor1
}
Repeater {
model: d.tagsModel
delegate: StatusListItemTag {
border.color: Theme.palette.baseColor2
color: "transparent"
height: 32
radius: 36
closeButtonVisible: false
asset.emoji: model.emoji
asset.height: 32
asset.width: asset.height
asset.color: "transparent"
asset.isLetterIdenticon: true
title: model.name
titleText.font.pixelSize: 15
titleText.color: Theme.palette.primaryColor1
}
GridLayout {
id: featuredGrid
Layout.leftMargin: d.layoutHMargin
columns: 3
columnSpacing: d.stylePadding
rowSpacing: d.stylePadding
Repeater {
model: d.featuredCommunitiesModel
delegate: StatusCommunityCard {
locale: "es"
communityId: model.communityId
loaded: model.available
logo: model.logo
name: model.name
description: model.description
members: model.members
popularity: model.popularity
communityColor: model.communityColor
categories: ListModel {
ListElement { name: "sport"; emoji: "🎾"}
ListElement { name: "food"; emoji: "🥑"}
ListElement { name: "privacy"; emoji: "👻"}
}
onClicked: { d.navigateToCommunity(communityId) }
}
}
}
StatusBaseText {
Layout.leftMargin: d.layoutHMargin
Layout.topMargin: 20
text: qsTr("Featured")
font.weight: Font.Bold
font.pixelSize: d.subtitlePixelSize
color: Theme.palette.directColor1
}
StatusBaseText {
Layout.leftMargin: d.layoutHMargin
Layout.topMargin: 20
text: qsTr("Popular")
font.weight: Font.Bold
font.pixelSize: d.subtitlePixelSize
color: Theme.palette.directColor1
}
GridLayout {
id: featuredGrid
Layout.leftMargin: d.layoutHMargin
columns: 3
columnSpacing: d.stylePadding
rowSpacing: d.stylePadding
GridLayout {
Layout.leftMargin: d.layoutHMargin
columns: 3
columnSpacing: d.stylePadding
rowSpacing: d.stylePadding
Repeater {
model: d.featuredCommunitiesModel
delegate: StatusCommunityCard {
locale: "es"
communityId: model.communityId
loaded: model.available
logo: model.logo
name: model.name
description: model.description
members: model.members
popularity: model.popularity
communityColor: model.communityColor
categories: ListModel {
ListElement { name: "sport"; emoji: "🎾"}
ListElement { name: "food"; emoji: "🥑"}
ListElement { name: "privacy"; emoji: "👻"}
}
Repeater {
model: d.popularCommunitiesModel
delegate: StatusCommunityCard {
locale: "es"
communityId: model.communityId
loaded: model.available
logo: model.logo
name: model.name
description: model.description
members: model.members
activeUsers: model.activeUsers
popularity: model.popularity
tokenLogo: model.tokenLogo
isPrivate: model.isPrivate
banner: model.banner
onClicked: { d.navigateToCommunity(communityId) }
}
}
}
StatusBaseText {
Layout.leftMargin: d.layoutHMargin
Layout.topMargin: 20
text: qsTr("Popular")
font.weight: Font.Bold
font.pixelSize: d.subtitlePixelSize
color: Theme.palette.directColor1
}
GridLayout {
Layout.leftMargin: d.layoutHMargin
columns: 3
columnSpacing: d.stylePadding
rowSpacing: d.stylePadding
Repeater {
model: d.popularCommunitiesModel
delegate: StatusCommunityCard {
locale: "es"
communityId: model.communityId
loaded: model.available
logo: model.logo
name: model.name
description: model.description
members: model.members
activeUsers: model.activeUsers
popularity: model.popularity
tokenLogo: model.tokenLogo
isPrivate: model.isPrivate
banner: model.banner
onClicked: { d.navigateToCommunity(communityId) }
}
}
onClicked: { d.navigateToCommunity(communityId) }
}
}
}
+78 -109
View File
@@ -1,6 +1,5 @@
import QtQuick 2.12
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.12
import StatusQ.Core 0.1
import StatusQ.Popups 0.1
@@ -11,7 +10,7 @@ import StatusQ.Core.Theme 0.1
import "data" 1.0
StatusSectionLayout {
StatusAppThreePanelLayout {
id: root
property string communityDetailModalTitle: ""
@@ -23,101 +22,6 @@ StatusSectionLayout {
color: SplitHandle.pressed ? Theme.palette.baseColor2
: (SplitHandle.hovered ? Qt.darker(Theme.palette.baseColor5, 1.1) : "transparent")
}
headerContent: RowLayout {
id: statusToolBar
StatusFlatRoundButton {
id: searchButton
Layout.alignment: Qt.AlignLeft
Layout.leftMargin: padding
icon.name: "search"
type: StatusFlatRoundButton.Type.Secondary
// initializing the tooltip
tooltip.text: qsTr("Search")
tooltip.orientation: StatusToolTip.Orientation.Bottom
tooltip.y: parent.height + 12
onClicked: {
searchButton.highlighted = !searchButton.highlighted;
searchPopup.setSearchSelection(communityDetailModalTitle,
"",
communityDetailModalImage);
searchPopup.open();
}
}
StatusChatInfoButton {
Layout.preferredWidth: Math.min(implicitWidth, parent.width)
Layout.fillHeight: true
title: "general"
subTitle: "Community Chat"
asset.color: Theme.palette.miscColor6
type: StatusChatInfoButton.Type.CommunityChat
}
Item {
Layout.fillWidth: true
}
StatusFlatRoundButton {
id: membersButton
icon.name: "group-chat"
type: StatusFlatRoundButton.Type.Secondary
// initializing the tooltip
tooltip.text: qsTr("Members")
tooltip.orientation: StatusToolTip.Orientation.Bottom
tooltip.y: parent.height + 12
onClicked: {
membersButton.highlighted = !membersButton.highlighted;
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: {
statusToolBar.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
}
}
leftPanel: Item {
id: leftPanel
@@ -129,9 +33,8 @@ StatusSectionLayout {
chatInfoButton.title: "CryptoKitties"
chatInfoButton.subTitle: "128 Members"
chatInfoButton.asset.isImage: true
chatInfoButton.asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
chatInfoButton.asset.color: Theme.palette.miscColor6
chatInfoButton.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
chatInfoButton.icon.color: Theme.palette.miscColor6
chatInfoButton.onClicked: { chatInfoButtonClicked(); }
popupMenu: StatusPopupMenu {
@@ -261,11 +164,79 @@ StatusSectionLayout {
}
centerPanel: Item {
anchors.fill: parent
StatusBaseText {
anchors.centerIn: parent
font.pixelSize: 15
text: qsTr("Community content here")
StatusChatToolBar {
id: statusChatToolBar
width: parent.width
toolbarComponent: statusChatInfoButton
onSearchButtonClicked: {
searchButton.highlighted = !searchButton.highlighted;
searchPopup.setSearchSelection(communityDetailModalTitle,
"",
communityDetailModalImage);
searchPopup.open();
}
membersButton.onClicked: membersButton.highlighted = !membersButton.highlighted
onMembersButtonClicked: {
root.showRightPanel = !root.showRightPanel;
}
Component {
id: statusChatInfoButton
StatusChatInfoButton {
width: Math.min(implicitWidth, parent.width)
title: "general"
subTitle: "Community Chat"
icon.color: Theme.palette.miscColor6
type: StatusChatInfoButton.Type.CommunityChat
}
}
}
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
}
}
@@ -302,10 +273,8 @@ StatusSectionLayout {
isVerified: model.isVerified
isUntrustworthy: model.isUntrustworthy
isContact: model.isContact
asset.name: model.icon
asset.isImage: (asset.name !== "")
asset.isLetterIdenticon: (asset.name === "")
asset.imgIsIdenticon: false
image.source: model.icon
image.isIdenticon: false
status: model.onlineStatus
}
}
@@ -8,7 +8,7 @@ import StatusQ.Core.Theme 0.1
import "data" 1.0
StatusSectionLayout {
StatusAppTwoPanelLayout {
id: root
leftPanel: Item {
@@ -41,7 +41,7 @@ StatusSectionLayout {
model: Models.demoProfileGeneralMenuItems
delegate: StatusNavigationListItem {
title: model.title
asset.name: model.icon
icon.name: model.icon
}
}
@@ -51,7 +51,7 @@ StatusSectionLayout {
model: Models.demoProfileSettingsMenuItems
delegate: StatusNavigationListItem {
title: model.title
asset.name: model.icon
icon.name: model.icon
}
}
@@ -65,7 +65,7 @@ StatusSectionLayout {
model: Models.demoProfileOtherMenuItems
delegate: StatusNavigationListItem {
title: model.title
asset.name: model.icon
icon.name: model.icon
}
}
}
File diff suppressed because one or more lines are too long
+3 -4
View File
@@ -35,7 +35,7 @@ ColumnLayout {
id: searchInput
Layout.fillWidth: true
input.asset.name: "search"
input.icon.name: "search"
placeholderText: "nickname.."
}
@@ -43,7 +43,7 @@ ColumnLayout {
id: contactBtn
icon.name: "tiny/tiny-contact"
identicon.asset.color: Theme.palette.primaryColor1
identicon.icon.color: Theme.palette.primaryColor1
onClicked: highlighted = !highlighted
}
@@ -51,7 +51,7 @@ ColumnLayout {
id: verifiedBtn
icon.name: "tiny/tiny-checkmark"
identicon.asset.color: Theme.palette.primaryColor1
identicon.icon.color: Theme.palette.primaryColor1
onClicked: highlighted = !highlighted
}
}
@@ -94,7 +94,6 @@ ColumnLayout {
nickName: model.nick
isVerified: model.isVerified
isContact: model.isContact
asset.isLetterIdenticon: true
}
}
+29 -47
View File
@@ -63,11 +63,11 @@ StatusWindow {
}
}
StatusMainLayout {
StatusAppLayout {
id: appLayout
anchors.fill: parent
leftPanel: StatusAppNavBar {
appNavBar: StatusAppNavBar {
height: rootWindow.height
communityTypeRole: "sectionType"
@@ -105,34 +105,30 @@ StatusWindow {
}
}
rightPanel: Item {
appView: StackView {
id: stackView
anchors.fill: parent
StackView {
id: stackView
anchors.fill: parent
initialItem: libraryDocumentationCmp
}
ThemeSwitch {
anchors.top: parent.top
anchors.topMargin: 32
anchors.right: parent.right
anchors.rightMargin: 32
lightThemeEnabled: storeSettings.lightTheme
onLightThemeEnabledChanged: {
Theme.palette = lightThemeEnabled ? rootWindow.darkTheme : rootWindow.lightTheme
storeSettings.lightTheme = lightThemeEnabled
}
}
initialItem: libraryDocumentationCmp
}
ThemeSwitch {
anchors.top: parent.top
anchors.topMargin: 32
anchors.right: parent.right
anchors.rightMargin: 32
lightThemeEnabled: storeSettings.lightTheme
onLightThemeEnabledChanged: {
Theme.palette = lightThemeEnabled ? rootWindow.darkTheme : rootWindow.lightTheme
storeSettings.lightTheme = lightThemeEnabled
}
}
}
Component {
id: libraryDocumentationCmp
StatusSectionLayout {
StatusAppTwoPanelLayout {
id: mainPageView
showHeader: false
function page(name, fillPage) {
storeSettings.fillPage = fillPage ? true : false
@@ -302,16 +298,6 @@ StatusWindow {
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
StatusNavigationListItem {
title: "StatusItemSelector"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title, true);
}
StatusNavigationListItem {
title: "StatusChartPanel"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title, true);
}
StatusListSectionHeadline { text: "StatusQ.Popup" }
StatusNavigationListItem {
title: "StatusPopupMenu"
@@ -357,8 +343,8 @@ StatusWindow {
}
}
centerPanel: Item {
id: centerPanel
rightPanel: Item {
id: rightPanel
anchors.fill: parent
StatusScrollView {
@@ -371,7 +357,7 @@ StatusWindow {
Item {
id: pageWrapper
width: centerPanel.width
width: rightPanel.width
anchors.top: parent.top
height: Math.max(rootWindow.height, viewLoader.height + 128)
scale: rootWindow.factor
@@ -429,9 +415,8 @@ StatusWindow {
Component {
id: examplesCmp
StatusSectionLayout {
StatusAppTwoPanelLayout {
id: examplesView
showHeader: false
function example(name) {
examplesLoader.source = Qt.resolvedUrl("./examples/" + name + ".qml")
@@ -459,19 +444,16 @@ StatusWindow {
}
}
centerPanel: Item {
rightPanel: StatusScrollView {
id: examplesRightPanel
anchors.fill: parent
StatusScrollView {
id: examplesCenterPanel
anchors.fill: parent
anchors.margins: 64
anchors.topMargin: anchors.margins + 32
anchors.margins: 64
anchors.topMargin: anchors.margins + 32
Loader {
id: examplesLoader
width: examplesCenterPanel.availableWidth
source: storeSettings.selectedExample !== "" ? storeSettings.selectedExample : examplesView.defaultExampleSource
}
Loader {
id: examplesLoader
width: examplesRightPanel.availableWidth
source: storeSettings.selectedExample !== "" ? storeSettings.selectedExample : examplesView.defaultExampleSource
}
}
}
-193
View File
@@ -1,193 +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 Sandbox 0.1
Item {
QtObject {
id: d
//dummy data
property real stepSize: 1000
property real minStep: 12000
property real maxStep: 22000
property var graphTabsModel: [{text: "Price", enabled: true}, {text: "Balance", enabled: false}]
property var timeRangeTabsModel: [{text: "1H", enabled: true},
{text: "1D", enabled: true},{text: "7D", enabled: true},
{text: "1M", enabled: true}, {text: "6M", enabled: true},
{text: "1Y", enabled: true}, {text: "ALL", enabled: true}]
property var simTimer: Timer {
running: true
interval: 3000
repeat: true
onTriggered: {
d.generateData();
}
}
function minutes(minutes = 0) {
var newMinute = new Date(new Date().getTime() - (minutes * 60 * 1000)).toString();
if (newMinute.slice(10,12) === "00") {
var dateToday = new Date(Date.now()).toString();
return dateToday.slice(4,7) + " " + dateToday.slice(8,10);
}
return newMinute.slice(10,16);
}
function hour(hours = 0) {
var newHour = new Date(new Date().getTime() - (hours * 60 * 60 * 1000)).toString();
if (newHour.slice(10,12) === "00") {
var dateToday = new Date(Date.now()).toString();
return dateToday.slice(4,7) + " " + dateToday.slice(8,10);
}
return newHour.slice(10,16);
}
function day(before = 0) {
var newDay = new Date(Date.now() - before * 24 * 60 * 60 * 1000).toString();
return newDay.slice(4,7) + " " + newDay.slice(8,10);
}
function month(before = 0) {
var newMonth = new Date(Date.now() - before * 24 * 60 * 60 * 1000).toString();
return newMonth.slice(4,7) + " '" + newMonth.slice(newMonth.indexOf("G")-3, newMonth.indexOf("G")-1);
}
property var timeRange: [
{'1H': [minutes(60), minutes(55), minutes(50), minutes(45), minutes(40), minutes(35), minutes(30), minutes(25), minutes(20), minutes(15), minutes(10), minutes(5), minutes()]},
{'1D': [hour(24), hour(23), hour(22), hour(21), hour(20), hour(19), hour(18), hour(17), hour(16), hour(15), hour(14), hour(13),
hour(12), hour(11), hour(10), hour(9), hour(8), hour(7), hour(6), hour(5), hour(4), hour(3), hour(2), hour(1), hour()]},
{'7D': [day(6), day(5), day(4), day(3), day(2), day(1), day()]},
{'1M': [day(30), day(28), day(26), day(24), day(22), day(20), day(18), day(16), day(14), day(12), day(10), day(8), day(6), day(4), day()]},
{'6M': [month(150), month(120), month(90), month(60), month(30), month()]},
{'1Y': [month(330), month(300), month(270), month(240), month(210), month(180), month(150), month(120), month(90), month(60), month(30), month()]},
{'ALL': ['2016', '2017', '2018', '2019', '2020', '2021', '2022']}
]
function generateData() {
var result = [];
for (var i = 0; i < timeRange[graphDetail.timeRangeTabBarIndex][graphDetail.selectedTimeRange].length; ++i) {
result[i] = Math.random() * (maxStep - minStep) + minStep;
}
graphDetail.chart.chartData.datasets[0].data = result;
graphDetail.chart.animateToNewData();
}
}
StatusChartPanel {
id: graphDetail
height: 290
anchors.left: parent.left
anchors.leftMargin: 24
anchors.right: parent.right
anchors.rightMargin: 24
anchors.verticalCenter: parent.verticalCenter
graphsModel: d.graphTabsModel
timeRangeModel: d.timeRangeTabsModel
onHeaderTabClicked: {
//TODO
//if time range tab
d.generateData();
//if graph bar
//switch graph
}
chart.chartType: 'line'
chart.chartData: {
return {
labels: d.timeRange[graphDetail.timeRangeTabBarIndex][graphDetail.selectedTimeRange],
datasets: [{
label: 'Price',
xAxisId: 'x-axis-1',
yAxisId: 'y-axis-1',
backgroundColor: (Theme.palette.name === "dark") ? 'rgba(136, 176, 255, 0.2)' : 'rgba(67, 96, 223, 0.2)',
borderColor: (Theme.palette.name === "dark") ? 'rgba(136, 176, 255, 1)' : 'rgba(67, 96, 223, 1)',
borderWidth: 3,
pointRadius: 0,
//data: d.generateData()
}]
}
}
chart.chartOptions: {
return {
maintainAspectRatio: false,
responsive: true,
legend: {
display: false
},
//TODO enable zoom
// zoom: {
// enabled: true,
// drag: true,
// speed: 0.1,
// threshold: 2
// },
// pan:{enabled:true,mode:'x'},
tooltips: {
intersect: false,
displayColors: false,
callbacks: {
footer: function(tooltipItem, data) { return 'Vol: $43,042,678,876'; },
label: function(tooltipItem, data) {
let label = data.datasets[tooltipItem.datasetIndex].label || '';
if (label) {
label += ': ';
}
label += tooltipItem.yLabel.toFixed(2);
return label.slice(0,label.indexOf(":")+1)+ " $"+label.slice(label.indexOf(":")+2, label.length);
}
}
},
scales: {
xAxes: [{
id: 'x-axis-1',
position: 'bottom',
gridLines: {
drawOnChartArea: false,
drawBorder: false,
drawTicks: false,
},
ticks: {
fontSize: 10,
fontColor: (Theme.palette.name === "dark") ? '#909090' : '#939BA1',
padding: 16
}
}],
yAxes: [{
position: 'left',
id: 'y-axis-1',
gridLines: {
borderDash: [8, 4],
drawBorder: false,
drawTicks: false,
color: (Theme.palette.name === "dark") ? '#909090' : '#939BA1'
},
beforeDataLimits: (axis) => {
axis.paddingTop = 25;
axis.paddingBottom = 0;
},
ticks: {
fontSize: 10,
fontColor: (Theme.palette.name === "dark") ? '#909090' : '#939BA1',
padding: 8,
min: d.minStep,
max: d.maxStep,
stepSize: d.stepSize,
callback: function(value, index, ticks) {
return '$' + value;
},
}
}]
}
}
}
}
}
+2 -3
View File
@@ -14,9 +14,8 @@ GridLayout {
StatusChatInfoToolBar {
chatInfoButton.title: "Cryptokitties"
chatInfoButton.subTitle: "128 Members"
chatInfoButton.asset.isImage: true
chatInfoButton.asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
chatInfoButton.asset.color: Theme.palette.miscColor6
chatInfoButton.image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
chatInfoButton.icon.color: Theme.palette.miscColor6
popupMenu: StatusPopupMenu {
+1 -1
View File
@@ -36,7 +36,7 @@ Item {
leftPadding: 0
rightPadding: 0
label: qsTr("Select tags that will fit your Community")
input.asset.name: "search"
input.icon.name: "search"
placeholderText: qsTr("Search tags")
Layout.fillWidth: true
}
@@ -26,7 +26,7 @@ Column {
anchors.horizontalCenter: parent.horizontalCenter
expandable: false
asset.name: "seed-phrase"
icon.name: "seed-phrase"
primaryText: "Back up seed phrase"
secondaryText: "Back up your seed phrase now to secure this account ajhaDH SDHSAHDLSADBSA,DLISAHDLASD ADASDHASLDHALSDHAS DAS,DASJDGLIASGD"
button.text: qsTr("Back up seed phrase")
@@ -36,7 +36,7 @@ Column {
anchors.horizontalCenter: parent.horizontalCenter
expandable: true
asset.name: "secret"
icon.name: "secret"
primaryText: "Account signing phrase"
secondaryText: "View your signing phrase and ensure that you never get scammed. View your signing phrase and ensure that you never get scammed."
expandableComponent: notImplemented
@@ -46,7 +46,7 @@ Column {
anchors.horizontalCenter: parent.horizontalCenter
expandable: true
asset.name: "seed-phrase"
icon.name: "seed-phrase"
primaryText: "View private key"
secondaryText: "Back up your seed phrase now to secure this account"
expandableComponent: notImplemented
@@ -74,8 +74,7 @@ Column {
type: StatusExpandableItem.Type.Secondary
expandable: true
asset.isImage: true
asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
primaryText: "CryptoKitties"
additionalText: "1456 USD"
expandableComponent: notImplemented
@@ -86,8 +85,7 @@ Column {
type: StatusExpandableItem.Type.Secondary
expandable: true
asset.isImage: true
asset.name: "qrc:/demoapp/data/profile-image-1.jpeg"
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
primaryText: "Adding Really long text to test scenario of having very long text along with tertiary text"
additionalText: "564.90 USD"
expandableComponent: notImplemented
+13 -21
View File
@@ -33,8 +33,9 @@ Column {
StatusInput {
label: "Label"
input.asset.name: "search"
input.placeholderText: "Input with icon"
input.icon.name: "search"
placeholderText: "Input with icon"
}
StatusInput {
@@ -56,15 +57,6 @@ Column {
input.clearable: true
}
StatusPasswordInput {
placeholderText: "Password"
}
StatusPasswordInput {
signingPhrase: "orange hello cygnet"
placeholderText: "Password"
}
Item {
implicitWidth: 480
implicitHeight: 82
@@ -120,9 +112,9 @@ Column {
StatusInput {
label: "StatusInput"
secondaryLabel: "with right icon"
input.asset.width: 15
input.asset.height: 11
input.asset.name: text !== "" ? "checkmark" : ""
input.icon.width: 15
input.icon.height: 11
input.icon.name: text !== "" ? "checkmark" : ""
input.leftIcon: false
}
@@ -200,9 +192,9 @@ Column {
StatusInput {
property bool toggled: true
label: "Input with emoji icon"
input.placeholderText: "Enter Name"
input.asset.emoji: toggled ? "😁" : "🧸"
input.asset.color: "blue"
placeholderText: "Enter Name"
input.icon.emoji: toggled ? "😁" : "🧸"
input.icon.color: "blue"
input.isIconSelectable: true
onIconClicked: {
toggled = !toggled
@@ -212,10 +204,10 @@ Column {
StatusInput {
property bool toggled: true
label: "Input with selectable icon which is not an emoji"
input.placeholderText: "Enter Name"
input.asset.emoji: ""
input.asset.name: toggled ? "filled-account" : "image"
input.asset.color: "blue"
placeholderText: "Enter Name"
input.icon.emoji: ""
input.icon.name: toggled ? "filled-account" : "image"
input.icon.color: "blue"
input.isIconSelectable: true
onIconClicked: {
toggled = !toggled
+3 -22
View File
@@ -1,4 +1,4 @@
import QtQuick 2.14
import QtQuick 2.0
import QtQuick.Layouts 1.14
import StatusQ.Components 0.1
@@ -15,44 +15,25 @@ ColumnLayout {
defaultItemText: "Example: Empty items"
andOperatorText: "and"
orOperatorText: "or"
itemsModel: ListModel {
id: model
}
StatusDropdown {
popupItem: StatusDropdown {
id: dropdown
parent: selector.addButton
width: 200
contentItem: ColumnLayout {
spacing: 10
StatusInput {
id: input
text: "Sample"
Layout.fillWidth: true
}
StatusButton {
Layout.alignment: Qt.AlignHCenter
text: "Add element"
onClicked: {
model.append({
text: input.text,
imageSource: "qrc:/images/SNT.png",
operator: model.count > 0 ? Utils.Operators.Or : Utils.Operators.None
})
selector.addItem(input.text, "qrc:/images/SNT.png", selector.itemsModel.count > 0 ? Utils.Operators.Or : Utils.Operators.None)
dropdown.close()
}
}
}
}
addButton.onClicked: {
dropdown.x = mouse.x
dropdown.y = mouse.y
dropdown.open()
}
}
StatusButton {
-69
View File
@@ -72,73 +72,4 @@ Column {
text: "Introduced PIN: " + regexPinInput.pinInput
font.pixelSize: 12
}
// PUK input that accepts only numbers
StatusBaseText {
topPadding: 100
anchors.horizontalCenter: parent.horizontalCenter
color: Theme.palette.directColor1
text: "Enter Keycard PUK"
font.pixelSize: 30
font.bold: true
}
StatusPinInput {
id: numbersPukInput
anchors.horizontalCenter: parent.horizontalCenter
validator: StatusRegularExpressionValidator { regularExpression: /[0-9]+/ }
pinLen: 12
}
StatusBaseText {
anchors.horizontalCenter: parent.horizontalCenter
color: Theme.palette.dangerColor1
text: "Only numbers allowed"
font.pixelSize: 16
}
StatusBaseText {
anchors.horizontalCenter: parent.horizontalCenter
color: Theme.palette.directColor1
text: "Introduced PUK: " + numbersPukInput.pinInput
font.pixelSize: 12
}
// PUK input that accepts only numbers
StatusBaseText {
topPadding: 100
anchors.horizontalCenter: parent.horizontalCenter
color: Theme.palette.directColor1
text: "Enter Keycard PUK"
font.pixelSize: 30
font.bold: true
}
StatusPinInput {
id: numbersPukInputWithSpacing
anchors.horizontalCenter: parent.horizontalCenter
validator: StatusRegularExpressionValidator { regularExpression: /[0-9]+/ }
pinLen: 12
additionalSpacing: 32
additionalSpacingOnEveryNItems: 4
Component.onCompleted: {
numbersPukInputWithSpacing.statesInitialization()
numbersPukInputWithSpacing.forceFocus()
}
}
StatusBaseText {
anchors.horizontalCenter: parent.horizontalCenter
color: Theme.palette.dangerColor1
text: "Only numbers allowed"
font.pixelSize: 16
}
StatusBaseText {
anchors.horizontalCenter: parent.horizontalCenter
color: Theme.palette.directColor1
text: "Introduced PUK: " + numbersPukInputWithSpacing.pinInput
font.pixelSize: 12
}
}
+43 -31
View File
@@ -22,8 +22,8 @@ GridLayout {
onClicked: complexMenu.popup()
}
StatusButton {
id: customPopupButton
text: "Menu with custom images and icons"
onClicked: customMenu.popup()
}
@@ -51,51 +51,61 @@ GridLayout {
StatusPopupMenu {
id: complexMenu
subMenuItemIcons: [{ icon: 'info' }]
// subMenuItemIcons: [{ icon: 'info' }]
StatusMenuItem {
text: "One"
assetSettings.name: "info"
iconSettings.name: "info"
}
StatusMenuSeparator {}
StatusMenuItem {
text: "Two"
assetSettings.name: "info"
iconSettings.name: "info"
}
StatusMenuItem {
text: "Three"
assetSettings.name: "info"
iconSettings.name: "info"
enabled: false
}
StatusPopupMenu {
title: "Four"
iconSettings.name: "info"
StatusMenuItem {
text: "One"
assetSettings.name: "info"
iconSettings.name: "info"
}
StatusMenuItem {
text: "Three"
assetSettings.name: "info"
iconSettings.name: "info"
}
}
}
StatusPopupMenu {
id: customMenu
width: customPopupButton.width
subMenuItemIcons: [
{ icon: "chat" },
{
source: "qrc:/demoapp/data/profile-image-1.jpeg"
},
{
isLetterIdenticon: true,
color: "red"
}
]
// subMenuItemIcons: [
// {
// icon: "chat"
// },
// {
// source: "qrc:/demoapp/data/profile-image-1.jpeg"
// },
// {
// isLetterIdenticon: true,
// color: "red"
// }
// ]
MenuItem {
text: "Default MenuItem, action: " + action
}
StatusMenuItem {
text: "Anywhere"
@@ -104,53 +114,55 @@ GridLayout {
StatusMenuSeparator {}
StatusPopupMenu {
title: "Chat"
title: "Chat"
iconSettings.name: "chat"
StatusMenuItem {
text: "vitalik.eth"
assetSettings.isImage: true
assetSettings.name: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0Bh
CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
assetSettings.imgIsIdenticon: true
image.isIdenticon: true
}
StatusMenuItem {
text: "Pascal"
assetSettings.isImage: true
assetSettings.name: "qrc:/demoapp/data/profile-image-1.jpeg"
image.source: "qrc:/demoapp/data/profile-image-1.jpeg"
}
}
StatusPopupMenu {
title: "Cryptokitties"
imageSettings.source: "qrc:/demoapp/data/profile-image-1.jpeg"
StatusMenuItem {
text: "welcome"
assetSettings.name: "channel"
assetSettings.color: Theme.palette.directColor1
iconSettings.name: "channel"
iconSettings.color: Theme.palette.directColor1
}
StatusMenuItem {
text: "support"
assetSettings.name: "channel"
assetSettings.color: Theme.palette.directColor1
iconSettings.name: "channel"
iconSettings.color: Theme.palette.directColor1
}
StatusMenuHeadline { text: "Public" }
StatusMenuItem {
text: "news"
assetSettings.name: "channel"
assetSettings.color: Theme.palette.directColor1
iconSettings.name: "channel"
iconSettings.color: Theme.palette.directColor1
}
}
StatusPopupMenu {
title: "Another community"
iconSettings.isLetterIdenticon: true
iconSettings.color: "red"
StatusMenuItem {
text: "welcome"
assetSettings.isLetterIdenticon: true
assetSettings.bgColor: "red"
iconSettings.isLetterIdenticon: true
iconSettings.background.color: "red"
}
}
}
+1 -2
View File
@@ -41,9 +41,8 @@ Column {
model: commmonModel
selectMenu.delegate: StatusMenuItemDelegate {
statusPopupMenu: select
action: StatusMenuItem {
assetSettings.name: "filled-account"
iconSettings.name: "filled-account"
text: name
onTriggered: {
selectedItem.text = name
+3
View File
@@ -75,8 +75,11 @@
<file>main.qml</file>
<file>ThemeSwitch.qml</file>
<file>examples/FilteringSorting.qml</file>
<file>images/RARI.png</file>
<file>images/SRToken.png</file>
<file>demoapp/data/profile-image-1.jpeg</file>
<file>demoapp/data/profile-image-2.jpeg</file>
<file>pages/StatusItemSelectorPage.qml</file>
<file>pages/StatusComboBoxPage.qml</file>
</qresource>
</RCC>
+5 -5
View File
@@ -239,7 +239,7 @@ Rectangle {
id: waitTimer
interval: lockTimeout
onTriggered: {
if(advancedInput.text)
if(advancedInput.edit.text)
advancedInput.locked = true
}
}
@@ -311,7 +311,7 @@ Rectangle {
}
PropertyChanges {
target: advancedInput
input.color: Theme.palette.directColor1
edit.color: Theme.palette.directColor1
}
PropertyChanges {
target: basicInput
@@ -370,7 +370,7 @@ Rectangle {
}
PropertyChanges {
target: advancedInput
input.edit.color: disabled ? Theme.palette.directColor5 : Theme.palette.dangerColor1
edit.color: disabled ? Theme.palette.directColor5 : Theme.palette.dangerColor1
}
PropertyChanges {
target: basicInput
@@ -429,7 +429,7 @@ Rectangle {
}
PropertyChanges {
target: advancedInput
input.color: Theme.palette.directColor1
edit.color: Theme.palette.directColor1
}
PropertyChanges {
target: basicInput
@@ -488,7 +488,7 @@ Rectangle {
}
PropertyChanges {
target: advancedInput
input.color: Theme.palette.directColor1
edit.color: Theme.palette.directColor1
}
PropertyChanges {
target: basicInput
-144
View File
@@ -1,144 +0,0 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import StatusQ.Controls 0.1
import "private/chart"
/*!
\qmltype StatusChartPanel
\inherits Page
\inqmlmodule StatusQ.Components
\since StatusQ.Components 0.1
\brief Displays a chart component together with an optional header in order to add a list of options.
Inherits \l{https://doc.qt.io/qt-5/qml-qtquick-controls2-page.html}{Page}.
The \c StatusChartPanel displays a customizable chart component. Additionally, options
can be added in the header in both right and left sides given graphTabsModel and timeRangeTabsModel
property are set respectively.
For example:
\qml
StatusChartPanel {
id: graphDetail
width: parent.width
height: 290
anchors.verticalCenter: parent.verticalCenter
graphsModel: d.graphTabsModel
timeRangeModel: d.timeRangeTabsModel
chart.chartType: 'line'
chart.chartData: {
return {
datasets: [{
data: d.data
}],
...
}
}
chart.chartOptions: {
return {
legend: {
display: false
},
...
}
}
}
\endqml
\image status_chart_panel.png
For a list of components available see StatusQ.
*/
Page {
id: root
/*!
\qmlproperty var StatusChartPanel::graphsModel
This property holds the graphs model options to be set on the left side tab bar of the header.
*/
property var graphsModel
/*!
\qmlproperty var StatusChartPanel::timeRangeModel
This property holds the time range options to be set on the right side tab bar of the header.
*/
property var timeRangeModel
/*!
\qmlproperty alias StatusChartPanel::graphComponent
This property holds holds a reference to the graph component.
*/
property alias chart: graphComponent
/*!
\qmlproperty alias StatusChartPanel::timeRangeTabBarIndex
This property holds holds a reference to the time range tab bar current index.
*/
property alias timeRangeTabBarIndex: timeRangeTabBar.currentIndex
/*!
\qmlproperty string StatusChartPanel::selectedTimeRange
This property holds holds the text of the current time range tab bar selected tab.
*/
property string selectedTimeRange: timeRangeTabBar.currentItem.text
/*!
\qmlsignal
This signal is emitted when a header tab bar is clicked.
*/
signal headerTabClicked(string text)
Component {
id: tabButton
StatusTabButton {
leftPadding: 0
width: implicitWidth
onClicked: {
root.headerTabClicked(text);
}
}
}
Component.onCompleted: {
if (!!timeRangeModel) {
for (var i = 0; i < timeRangeModel.length; i++) {
var timeTab = tabButton.createObject(root, { text: timeRangeModel[i].text,
enabled: timeRangeModel[i].enabled });
timeRangeTabBar.addItem(timeTab);
}
}
if (!!graphsModel) {
for (var j = 0; j < graphsModel.length; j++) {
var graphTab = tabButton.createObject(root, { text: graphsModel[j].text,
enabled: graphsModel[j].enabled });
graphsTabBar.addItem(graphTab);
}
}
}
background: null
header: Item {
height: childrenRect.height
RowLayout {
anchors.left: parent.left
anchors.leftMargin: 46
anchors.right: parent.right
StatusTabBar {
id: graphsTabBar
}
StatusTabBar {
id: timeRangeTabBar
Layout.alignment: Qt.AlignRight
}
}
}
contentItem: Item {
Chart {
id: graphComponent
anchors.fill: parent
}
}
}
+8 -8
View File
@@ -118,12 +118,12 @@ Column {
notificationsCount: model.notificationsCount
highlightWhenCreated: !!model.highlight
selected: (model.active && root.highlightItem)
asset.emoji: !!model.emoji ? model.emoji : ""
asset.color: !!model.color ? model.color : Theme.palette.userCustomizationColors[model.colorId]
asset.isImage: model.icon.includes("data")
asset.name: model.icon
icon.emoji: model.emoji
icon.color: !!model.color ? model.color : Theme.palette.userCustomizationColors[model.colorId]
image.isIdenticon: false
image.source: model.icon
ringSettings.ringSpecModel: model.colorHash
onlineStatus: model.onlineStatus
sensor.cursorShape: dragSensor.cursorShape
@@ -228,9 +228,9 @@ Column {
notificationsCount: model.notificationsCount
selected: draggable.chatListItem.selected
asset.color: draggable.chatListItem.asset.color
asset.imgIsIdenticon: draggable.chatListItem.asset.imgIsIdenticon
asset.name: draggable.chatListItem.asset.name
icon.color: draggable.chatListItem.icon.color
image.isIdenticon: draggable.chatListItem.image.isIdenticon
image.source: draggable.chatListItem.image.source
}
}
}
@@ -32,7 +32,7 @@ Item {
property bool draggableCategories: false
// Keeps track of expanded category state. Should only be modified
// internally at runtime.
property var openedCategoryState: ({})
property var openedCategoryState: new Object({})
property Component categoryPopupMenu
property Component chatListPopupMenu
@@ -71,7 +71,6 @@ Item {
spacing: 4
StatusChatList {
objectName: "statusChatListAndCategoriesChatList"
id: statusChatList
visible: statusChatList.model.count > 0
onChatItemSelected: root.chatItemSelected(categoryId, id)
@@ -114,7 +113,6 @@ Item {
delegate: Item {
id: draggable
objectName: model.name
width: statusChatListCategory.width
height: statusChatListCategory.height
property alias chatListCategory: statusChatListCategory
@@ -261,7 +259,6 @@ Item {
Repeater {
id: statusChatListCategories
objectName: "communityChatListCategories"
visible: !!model && model.count > 0
model: delegateModel
}
@@ -16,7 +16,6 @@ Column {
property bool opened: true
property bool dragged: false
property alias statusChatListCategoryItem: statusChatListCategoryItem
property alias showActionButtons: statusChatListCategoryItem.showActionButtons
property alias addButton: statusChatListCategoryItem.addButton
property alias menuButton: statusChatListCategoryItem.menuButton
@@ -38,20 +37,20 @@ Column {
title: statusChatListCategory.name
opened: statusChatListCategory.opened
sensor.pressAndHoldInterval: 150
propagateTitleClicks: true // title click is handled as a normal click (fallthru)
showMenuButton: showActionButtons && !!statusChatListCategory.popupMenu
highlighted: statusChatListCategory.dragged
onClicked: {
sensor.onClicked: {
if (sensor.enabled) {
if (mouse.button === Qt.RightButton && showActionButtons && !!statusChatListCategory.popupMenu) {
highlighted = true;
popupMenuSlot.item.popup(mouse.x + 4, mouse.y + 6);
} else if (mouse.button === Qt.LeftButton) {
statusChatListCategory.opened = !statusChatListCategory.opened
return
}
}
}
onToggleButtonClicked: statusChatListCategory.opened = !statusChatListCategory.opened
onTitleClicked: statusChatListCategory.opened = !opened
onToggleButtonClicked: statusChatListCategory.opened = !opened
onMenuButtonClicked: {
highlighted = true
menuButton.highlighted = true
@@ -60,7 +60,15 @@ StatusListItem {
icon.name: "chevron-down"
icon.width: 18
icon.rotation: statusChatListCategoryItem.opened ? 0 : 270
onClicked: statusChatListCategoryItem.toggleButtonClicked(mouse)
onPressed: {
sensor.enabled = false;
}
onClicked: {
statusChatListCategoryItem.toggleButtonClicked(mouse);
}
onReleased: {
sensor.enabled = true;
}
}
]
}
+15 -23
View File
@@ -21,9 +21,11 @@ Rectangle {
property bool hasUnreadMessages: false
property int notificationsCount: 0
property bool muted: false
property int onlineStatus: StatusChatListItem.OnlineStatus.Inactive
property StatusAssetSettings asset: StatusAssetSettings {
property StatusImageSettings image: StatusImageSettings {
width: 24
height: 24
}
property StatusIconSettings icon: StatusIconSettings {
width: 24
height: 24
color: Theme.palette.miscColor5
@@ -51,11 +53,6 @@ Rectangle {
CommunityChat // 6
}
enum OnlineStatus {
Inactive,
Online
}
implicitWidth: 288
implicitHeight: 40
@@ -88,17 +85,9 @@ Rectangle {
anchors.left: parent.left
anchors.leftMargin: 8
anchors.verticalCenter: parent.verticalCenter
asset: root.asset
image: root.image
icon: root.icon
name: root.name
badge {
visible: type === StatusChatListItem.Type.OneToOneChat
color: onlineStatus === StatusChatListItem.OnlineStatus.Online ? Theme.palette.successColor1 : Theme.palette.baseColor1
border.width: 1
border.color: root.color
implicitHeight: 9
implicitWidth: 9
}
}
StatusIcon {
@@ -123,14 +112,17 @@ Rectangle {
icon: {
switch (root.type) {
case StatusChatListItem.Type.PublicChat:
return Theme.palette.name === "light" ? "tiny/public-chat" : "tiny/public-chat-white"
case StatusChatListItem.Type.PublicCat:
return Theme.palette.name == "light" ? "tiny/public-chat" : "tiny/public-chat-white"
break;
case StatusChatListItem.Type.GroupChat:
return Theme.palette.name === "light" ? "tiny/group" : "tiny/group-white"
return Theme.palette.name == "light" ? "tiny/group" : "tiny/group-white"
break;
case StatusChatListItem.Type.CommunityChat:
return Theme.palette.name === "light" ? "tiny/channel" : "tiny/channel-white"
return Theme.palette.name == "light" ? "tiny/channel" : "tiny/channel-white"
break;
default:
return Theme.palette.name === "light" ? "tiny/public-chat" : "tiny/public-chat-white"
return Theme.palette.name == "light" ? "tiny/public-chat" : "tiny/public-chat-white"
}
}
}
@@ -0,0 +1,149 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
Item {
id: statusChatToolBar
property alias menuButton: menuButton
property alias notificationButton: notificationButton
property alias membersButton: membersButton
property alias searchButton: searchButton
property int padding: 8
property int notificationCount: 0
property Component popupMenu
property var toolbarComponent
signal chatInfoButtonClicked()
signal menuButtonClicked()
signal notificationButtonClicked()
signal membersButtonClicked()
signal searchButtonClicked()
implicitWidth: 518
implicitHeight: 60
onPopupMenuChanged: {
if (!!popupMenu) {
popupMenuSlot.sourceComponent = popupMenu
}
}
RowLayout {
width: parent.width
spacing: padding / 2
Loader {
id: loader
sourceComponent: statusChatToolBar.toolbarComponent
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
Layout.topMargin: padding
Layout.leftMargin: padding
}
RowLayout {
id: actionButtons
Layout.alignment: Qt.AlignTop | Qt.AlignRight
Layout.topMargin: padding
Layout.rightMargin: padding
spacing: 8
StatusFlatRoundButton {
id: searchButton
width: 32
height: 32
icon.name: "search"
type: StatusFlatRoundButton.Type.Secondary
onClicked: statusChatToolBar.searchButtonClicked()
// initializing the tooltip
tooltip.text: qsTr("Search")
tooltip.orientation: StatusToolTip.Orientation.Bottom
tooltip.y: parent.height + 12
}
StatusFlatRoundButton {
id: membersButton
width: 32
height: 32
icon.name: "group-chat"
type: StatusFlatRoundButton.Type.Secondary
onClicked: statusChatToolBar.membersButtonClicked()
// initializing the tooltip
tooltip.text: qsTr("Members")
tooltip.orientation: StatusToolTip.Orientation.Bottom
tooltip.y: parent.height + 12
}
StatusFlatRoundButton {
id: menuButton
objectName: "chatToolbarMoreOptionsButton"
width: 32
height: 32
icon.name: "more"
type: StatusFlatRoundButton.Type.Secondary
visible: !!statusChatToolBar.popupMenu
// initializing the tooltip
tooltip.visible: !!tooltip.text && menuButton.hovered && !popupMenuSlot.item.opened
tooltip.text: qsTr("More")
tooltip.orientation: StatusToolTip.Orientation.Bottom
tooltip.y: parent.height + 12
property bool showMoreMenu: false
onClicked: {
menuButton.highlighted = true
let originalOpenHandler = popupMenuSlot.item.openHandler
let originalCloseHandler = popupMenuSlot.item.closeHandler
popupMenuSlot.item.openHandler = function () {
if (!!originalOpenHandler) {
originalOpenHandler()
}
}
popupMenuSlot.item.closeHandler = function () {
menuButton.highlighted = false
if (!!originalCloseHandler) {
originalCloseHandler()
}
}
popupMenuSlot.item.openHandler = originalOpenHandler
popupMenuSlot.item.popup(-popupMenuSlot.item.width + menuButton.width, menuButton.height + 4)
statusChatToolBar.menuButtonClicked()
}
Loader {
id: popupMenuSlot
active: !!statusChatToolBar.popupMenu
}
}
Rectangle {
height: 24
width: 1
color: Theme.palette.directColor7
Layout.alignment: Qt.AlignVCenter
visible: notificationButton.visible &&
(menuButton.visible || membersButton.visible || searchButton.visible)
}
StatusActivityCenterButton {
id: notificationButton
width: 32
height: width
unreadNotificationsCount: statusChatToolBar.notificationCount
onClicked: statusChatToolBar.notificationButtonClicked()
}
}
}
}
@@ -360,11 +360,11 @@ Rectangle {
height: 24
radius: 20
closeButtonVisible: false
asset.emoji: model.emoji
asset.width: 24
asset.height: 24
asset.color: "transparent"
asset.isLetterIdenticon: true
icon.emoji: model.emoji
icon.height: 24
icon.width: icon.height
icon.color: "transparent"
icon.isLetterIdenticon: true
title: model.name
titleText.font.pixelSize: 13
titleText.color: d.fontColor
@@ -9,14 +9,16 @@ Row {
property bool isContact: false
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
property StatusAssetSettings mutualConnectionIcon: StatusAssetSettings {
property StatusIconSettings mutualConnectionIcon: StatusIconSettings {
name: "tiny/tiny-contact"
color: Theme.palette.indirectColor1
width: dummyImage.width
height: dummyImage.height
bgWidth: 10
bgHeight: 10
bgColor: Theme.palette.primaryColor1
background: StatusIconBackgroundSettings {
width: 10
height: 10
color: Theme.palette.primaryColor1
}
// Only used to get implicit width and height from the actual image
property Image dummyImage: Image {
source: mutualConnectionIcon.name ? "../../assets/img/icons/" + mutualConnectionIcon.name + ".svg": ""
@@ -24,15 +26,17 @@ Row {
}
}
property StatusAssetSettings trustContactIcon: StatusAssetSettings {
property StatusIconSettings trustContactIcon: StatusIconSettings {
// None and Untrustworthy types, same aspect (Icon will not be visible in case of None type):
name: root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified ? "tiny/tiny-checkmark" : "tiny/subtract"
color: Theme.palette.indirectColor1
width: dummyImage.width
height: dummyImage.height
bgWidth: 10
bgHeight: 10
bgColor: root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified ? Theme.palette.primaryColor1 : Theme.palette.dangerColor1
background: StatusIconBackgroundSettings {
width: 10
height: 10
color: root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified ? Theme.palette.primaryColor1 : Theme.palette.dangerColor1
}
// Only used to get implicit width and height from the actual image
property Image dummyImage: Image {
source: trustContactIcon.name ? "../../assets/img/icons/" + trustContactIcon.name + ".svg": ""
@@ -51,25 +55,25 @@ Row {
StatusRoundIcon {
visible: root.isContact
asset.name: root.mutualConnectionIcon.name
asset.width: root.mutualConnectionIcon.width
asset.height: root.mutualConnectionIcon.height
asset.rotation: root.mutualConnectionIcon.rotation
asset.color: root.mutualConnectionIcon.color
asset.bgColor: root.mutualConnectionIcon.bgColor
asset.bgWidth: root.mutualConnectionIcon.bgWidth
asset.bgHeight: root.mutualConnectionIcon.bgHeight
icon.name: root.mutualConnectionIcon.name
icon.width: root.mutualConnectionIcon.width
icon.height: root.mutualConnectionIcon.height
icon.rotation: root.mutualConnectionIcon.rotation
icon.color: root.mutualConnectionIcon.color
icon.background.color: root.mutualConnectionIcon.background.color
icon.background.width: root.mutualConnectionIcon.background.width
icon.background.height: root.mutualConnectionIcon.background.height
}
StatusRoundIcon {
visible: root.trustIndicator !== StatusContactVerificationIcons.TrustedType.None
asset.name: root.trustContactIcon.name
asset.width: root.trustContactIcon.width
asset.height: root.trustContactIcon.height
asset.rotation: root.trustContactIcon.rotation
asset.color: root.trustContactIcon.color
asset.bgColor: root.trustContactIcon.bgColor
asset.bgWidth: root.trustContactIcon.bgWidth
asset.bgHeight: root.trustContactIcon.bgHeight
icon.name: root.trustContactIcon.name
icon.width: root.trustContactIcon.width
icon.height: root.trustContactIcon.height
icon.rotation: root.trustContactIcon.rotation
icon.color: root.trustContactIcon.color
icon.background.color: root.trustContactIcon.background.color
icon.background.width: root.trustContactIcon.background.width
icon.background.height: root.trustContactIcon.background.height
}
}
@@ -1,42 +0,0 @@
import QtQuick 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
StatusBaseText {
id: root
property int previousMessageIndex: -1
property double previousMessageTimestamp
property double messageTimestamp
font.pixelSize: 13
color: Theme.palette.baseColor1
horizontalAlignment: Text.AlignHCenter
text: {
if (previousMessageIndex === -1)
return "";
const currentMsgDate = new Date(messageTimestamp);
const prevMsgDate = new Date(previousMessageTimestamp);
if (!!prevMsgDate && currentMsgDate.getDay() === prevMsgDate.getDay())
return "";
const now = new Date();
if (now.getFullYear() == currentMsgDate.getFullYear() && now.getMonth() == currentMsgDate.getMonth() && now.getDate() == currentMsgDate.getDate())
return qsTr("Today");
const yesterday = new Date();
yesterday.setDate(now.getDate()-1);
if (yesterday.getFullYear() == currentMsgDate.getFullYear() && yesterday.getMonth() == currentMsgDate.getMonth() && yesterday.getDate() == currentMsgDate.getDate())
return qsTr("Yesterday");
// FIXME Qt6: replace with Intl.DateTimeFormat
const monthName = Qt.locale().standaloneMonthName(currentMsgDate.getMonth(), Locale.LongFormat)
if (now.getFullYear() > currentMsgDate.getFullYear())
return "%1 %2, %3".arg(monthName).arg(currentMsgDate.getDate()).arg(currentMsgDate.getFullYear())
return "%1, %2".arg(monthName).arg(currentMsgDate.getDate())
}
}
@@ -10,7 +10,7 @@ Rectangle {
property string subTitle: ""
property alias subTitleComponent: statusDescriptionListItemSubTitle
property string value: ""
property StatusAssetSettings asset: StatusAssetSettings {
property StatusIconSettings icon: StatusIconSettings {
width: 23
height: 23
}
@@ -59,7 +59,7 @@ Rectangle {
StatusFlatRoundButton {
id: statusFlatRoundButton
visible: !!statusDescriptionListItem.asset.name
visible: !!statusDescriptionListItem.icon.name
anchors.verticalCenter: statusDescriptionListItemSubTitle.verticalCenter
anchors.left: statusDescriptionListItemSubTitle.right
anchors.leftMargin: 4
@@ -67,9 +67,9 @@ Rectangle {
width: 32
height: 32
icon.name: statusDescriptionListItem.asset.name
icon.width: statusDescriptionListItem.asset.width
icon.height: statusDescriptionListItem.asset.height
icon.name: statusDescriptionListItem.icon.name
icon.width: statusDescriptionListItem.icon.width
icon.height: statusDescriptionListItem.icon.height
StatusToolTip {
id: statusToolTip
+23 -17
View File
@@ -13,19 +13,24 @@ Rectangle {
property alias button: button
property alias expandableComponent: expandableRegion.sourceComponent
property alias expandableItem: expandableRegion.item
property bool separatorVisible: true
property int type: StatusExpandableItem.Type.Primary
property bool expandable: true
property bool expanded: false
property StatusAssetSettings asset: StatusAssetSettings {
width: !statusExpandableItem.asset.isImage ? 24 : 40
height: !statusExpandableItem.asset.isImage ? 24 : 40
property StatusIconSettings icon: StatusIconSettings {
width: !!statusExpandableItem.icon.name.toString() ? 24 : 40
height: !!statusExpandableItem.icon.name.toString() ? 24 : 40
color: Theme.palette.directColor1
bgWidth: 32
bgHeight: 32
bgColor: Theme.palette.primaryColor2
background: StatusIconBackgroundSettings {
width: 32
height: 32
color: Theme.palette.primaryColor2
}
}
property StatusImageSettings image: StatusImageSettings {
width: 40
height: 40
}
enum Type {
@@ -50,7 +55,7 @@ Rectangle {
height: 1
color: Theme.palette.baseColor2
visible: (statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) && separatorVisible
visible: (statusExpandableItem.type === StatusExpandableItem.Type.Tertiary)
}
@@ -58,7 +63,7 @@ Rectangle {
id: header
anchors.top: parent.top
width: parent.width
height: statusExpandableItem.type === StatusExpandableItem.Type.Tertiary ? 40 : 64
height: 64
radius: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? 8 : 0
color: statusExpandableItem.type === StatusExpandableItem.Type.Secondary && sensor.containsMouse ? Theme.palette.baseColor2 : "transparent"
@@ -68,7 +73,8 @@ Rectangle {
anchors.topMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? 12.5 : 25
anchors.left: parent.left
anchors.leftMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? 16 : 11
asset: statusExpandableItem.asset
image: statusExpandableItem.image
icon: statusExpandableItem.icon
name: primaryText.text
active: (statusExpandableItem.type !== StatusExpandableItem.Type.Tertiary)
}
@@ -79,14 +85,14 @@ Rectangle {
(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 : !identicon.active ? 0 : 16
anchors.leftMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 10 : 16
anchors.verticalCenter: (statusExpandableItem.type === StatusExpandableItem.Type.Secondary) ? identicon.verticalCenter : undefined
width: !!additionalText.text ? (button.visible ? parent.width - asset.bgWidth - button.width - additionalText.contentWidth - 110 :
parent.width - asset.bgWidth - additionalText.contentWidth - 110) :
(button.visible ? parent.width - asset.bgWidth - button.width - 70 :
parent.width - asset.bgWidth - 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
@@ -175,7 +181,7 @@ Rectangle {
Loader {
id: expandableRegion
anchors.top: header.bottom
anchors.topMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Tertiary) ? 24 : 16
anchors.topMargin: 16
anchors.left: parent.left
anchors.leftMargin: (statusExpandableItem.type === StatusExpandableItem.Type.Primary) ? 48 : 0
anchors.right: parent.right
@@ -196,7 +202,7 @@ Rectangle {
State {
name: "EXPANDED"
PropertyChanges {target: expandImage; icon: "chevron-up"}
PropertyChanges {target: statusExpandableItem; height: 82 + expandableRegion.height}
PropertyChanges {target: statusExpandableItem; height: 82 + expandableRegion.height + 22}
PropertyChanges {target: expandableRegion; visible: true}
},
State {
@@ -216,7 +216,6 @@ Item {
anchors.fill: parent
enabled: root.interactive
cursorShape: Qt.SizeAllCursor
property var lastDragPoint: null
onReleased: lastDragPoint = null
+34 -46
View File
@@ -27,15 +27,12 @@ import StatusQ.Core.Utils 0.1
defaultItemText: qsTr("Example: 10 SNT")
andOperatorText: qsTr("and")
orOperatorText: qsTr("or")
CustomPopup {
id: popup
}
addButton.onClicked: {
popup.x = mouse.x
popup.y = mouse.y
popup.open()
popupItem: CustomPopup {
id: customPopup
onAddItem: {
tokensSelector.addItem(itemText, itemImage, operator)
customPopup.close()
}
}
}
\endqml
@@ -69,10 +66,10 @@ Rectangle {
*/
property url defaultItemImageSource: ""
/*!
\qmlproperty StatusRoundButton StatusItemSelector::addButton
This property holds an alias to the `add` button.
\qmlproperty QC.Popup StatusItemSelector::popupItem
This property holds a custom popup item to be opened near the `add` button in order to select new items.
*/
readonly property alias addButton: addItemButton
property QC.Popup popupItem
/*!
\qmlproperty ListModel StatusItemSelector::itemsModel
This property holds the data that will be populated in the items selector.
@@ -93,13 +90,7 @@ Rectangle {
}
\endqml
*/
property var itemsModel: ListModel { }
/*!
\qmlproperty bool StatusItemSelector::useIcons
This property determines if the imageSource role from the model will be handled as
an image or an icon.
*/
property bool useIcons: false
property ListModel itemsModel: ListModel { }
/*!
\qmlproperty string StatusItemSelector::andOperatorText
This property holds the string text representation for an `AND` logical operator.
@@ -110,24 +101,27 @@ Rectangle {
This property holds the string text representation for an `OR` logical operator.
*/
property string orOperatorText: qsTr("or")
/*!
\qmlsignal StatusItemSelector::itemClicked
This signal is emitted when the item is clicked.
/*
\qmlmethod StatusItemSelector::addItem()
It is used to add new items into the selector control. The expected arguments are:
string `text`, url `imageSource` and int `operator` (None = 0, And = 1 and Or = 2)
*/
signal itemClicked(var item, int index, var mouse)
function addItem(text, imageSource, operator) {
itemsModel.insert(itemsModel.count, { "text": text, "imageSource": imageSource.toString(), "operator": operator })
}
QtObject {
id: d
function operatorTextFormat(operator) {
switch(operator) {
case Utils.Operators.And:
return root.andOperatorText
case Utils.Operators.Or:
return root.orOperatorText
case Utils.Operators.None:
return ""
switch(operator)
{
case Utils.Operators.And:
return root.andOperatorText
case Utils.Operators.Or:
return root.orOperatorText
case Utils.Operators.None:
return ""
}
}
}
@@ -174,10 +168,9 @@ Rectangle {
Layout.fillWidth: true
spacing: 6
StatusListItemTag {
visible: !itemsModel || itemsModel.count === 0
visible: itemsModel.count === 0
title: root.defaultItemText
asset.name: root.defaultItemImageSource
asset.isImage: true
image.source: root.defaultItemImageSource
color: Theme.palette.baseColor2
closeButtonVisible: false
titleText.color: Theme.palette.baseColor1
@@ -185,10 +178,8 @@ Rectangle {
}
Repeater {
model: itemsModel
RowLayout {
spacing: flow.spacing
StatusBaseText {
visible: model.operator !== Utils.Operators.None
Layout.alignment: Qt.AlignVCenter
@@ -209,20 +200,12 @@ Rectangle {
}
StatusListItemTag {
title: model.text
asset.name: model.imageSource
asset.isImage: !root.useIcons
asset.bgColor: "transparent"
image.source: model.imageSource
color: Theme.palette.primaryColor3
closeButtonVisible: false
titleText.color: Theme.palette.primaryColor1
titleText.font.pixelSize: 15
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: root.itemClicked(parent, model.index, mouse)
}
//onClicked: // TODO: Open remove or edit dialog
}
}
}
@@ -233,6 +216,11 @@ Rectangle {
height: width
type: StatusRoundButton.Type.Secondary
icon.name: "add"
onClicked: {
root.popupItem.x = addItemButton.x + addItemButton.width + 4 * flow.spacing
root.popupItem.y = addItemButton.y + addItemButton.height
root.popupItem.open()
}
}
}
}
+58 -105
View File
@@ -23,42 +23,46 @@ Rectangle {
property string titleTextIcon: ""
property real leftPadding: 16
property real rightPadding: 16
property bool enabled: true
property bool highlighted: false
property bool propagateTitleClicks: true
property int type: StatusListItem.Type.Primary
property list<Item> components
property var bottomModel: []
property Component bottomDelegate
property alias tagsModel: tagsRepeater.model
property var tagsModel: []
property Component tagsDelegate
property var inlineTagModel: []
property Component inlineTagDelegate
property bool loading: false
property bool loadingFailed: false
property StatusAssetSettings asset: StatusAssetSettings {
height: isImage ? 40 : 20
width: isImage ? 40 : 20
property StatusIconSettings icon: StatusIconSettings {
height: isLetterIdenticon ? 40 : 20
width: isLetterIdenticon ? 40 : 20
rotation: 0
isLetterIdenticon: false
letterSize: 21
charactersLen: 1
color: isLetterIdenticon ? bgColor : type === StatusListItem.Type.Danger ?
color: isLetterIdenticon ? background.color : type === StatusListItem.Type.Danger ?
Theme.palette.dangerColor1 : Theme.palette.primaryColor1
bgWidth: 40
bgHeight: 40
bgColor: {
if (sensor.containsMouse) {
return type === StatusListItem.Type.Secondary ||
type === StatusListItem.Type.Danger ? "transparent" :
Theme.palette.primaryColor3
background: StatusIconBackgroundSettings {
width: 40
height: 40
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
}
return type === StatusListItem.Type.Danger ?
Theme.palette.dangerColor3 : Theme.palette.primaryColor3
}
imgIsIdenticon: false
}
property StatusImageSettings image: StatusImageSettings {
width: 40
height: 40
isIdenticon: false
}
property StatusIdenticonRingSettings ringSettings: StatusIdenticonRingSettings {
initalAngleRad: 0
ringPxSize: 1.5
@@ -118,32 +122,33 @@ Rectangle {
}
MouseArea {
id: sensor
enabled: statusListItem.enabled
anchors.fill: parent
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
hoverEnabled: true
preventStealing: true
onClicked: {
statusListItem.clicked(statusListItem.itemId, mouse)
}
}
MouseArea {
id: sensor
anchors.fill: parent
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.NoButton
hoverEnabled: true
StatusSmartIdenticon {
id: iconOrImage
anchors.left: parent.left
anchors.leftMargin: statusListItem.leftPadding
anchors.verticalCenter: parent.verticalCenter
anchors.top: parent.top
anchors.topMargin: 12
visible: !iconOrImageLoadingOverlay.visible
asset: statusListItem.asset
image: statusListItem.image
icon: statusListItem.icon
name: statusListItem.title
active: statusListItem.asset.isLetterIdenticon ||
!!statusListItem.asset.name ||
!!statusListItem.asset.emoji
active: statusListItem.icon.isLetterIdenticon ||
!!statusListItem.icon.name ||
!!statusListItem.image.source.toString() ||
!!statusListItem.icon.emoji
badge.border.color: statusListItem.color
ringSettings: statusListItem.ringSettings
}
@@ -176,7 +181,7 @@ Rectangle {
anchors.left: iconOrImage.active ? iconOrImage.right : parent.left
anchors.right: statusListItemLabel.visible ? statusListItemLabel.left : statusListItemComponentsSlot.left
anchors.leftMargin: iconOrImage.active ? 16 : statusListItem.leftPadding
anchors.rightMargin: Math.max(statusListItem.rightPadding, titleIconsRow.requiredWidth)
anchors.rightMargin: statusListItem.rightPadding
anchors.verticalCenter: bottomModel.length === 0 ? parent.verticalCenter : undefined
height: childrenRect.height
@@ -272,74 +277,30 @@ Rectangle {
Loader {
id: titleIconsRow
readonly property int requiredWidth: active ? width + anchors.leftMargin * 2 : 0
anchors.left: !statusListItem.titleAsideText ? statusListItemTitle.right : statusListItemTitleAsideText.right
anchors.verticalCenter: statusListItemTitle.verticalCenter
anchors.leftMargin: 4
}
RowLayout {
id: statusListItemSubtitleTagsRow
StatusBaseText {
id: statusListItemSubTitle
objectName: "statusListItemSubTitle"
anchors.top: statusListItemTitle.bottom
width: parent.width
spacing: 4
StatusBaseText {
id: statusListItemSubTitle
objectName: "statusListItemSubTitle"
Layout.alignment: Qt.AlignVCenter
Layout.preferredWidth: inlineTagModelRepeater.count > 0 ? contentWidth : parent.width
text: statusListItem.subTitle
font.pixelSize: 15
color: statusListItem.loadingFailed ? Theme.palette.dangerColor1
: !statusListItem.enabled || !statusListItem.tertiaryTitle
? Theme.palette.baseColor1
: Theme.palette.directColor1
visible: !!statusListItem.subTitle
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
StatusBaseText {
id: dot
Layout.alignment: Qt.AlignVCenter
Layout.topMargin: -48
text: "."
font.pixelSize: 40
color: Theme.palette.baseColor1
lineHeightMode: Text.FixedHeight
lineHeight: 24
visible: inlineTagModelRepeater.count > 0
}
StatusScrollView {
id: inlineTagModelRepeaterRow
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
Layout.preferredHeight: row.height
contentHeight: row.height
contentWidth: row.width
padding: 0
clip: true
Row {
id: row
Repeater {
id: inlineTagModelRepeater
model: inlineTagModel
delegate: inlineTagDelegate
}
}
}
text: statusListItem.subTitle
font.pixelSize: 15
color: statusListItem.loadingFailed ? Theme.palette.dangerColor1
: !statusListItem.enabled || !statusListItem.tertiaryTitle
? Theme.palette.baseColor1
: Theme.palette.directColor1
height: visible ? contentHeight : 0
visible: !!statusListItem.subTitle
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
StatusBaseText {
id: statusListItemTertiaryTitle
anchors.top: statusListItemSubtitleTagsRow.bottom
anchors.top: statusListItemSubTitle.bottom
width: parent.width
height: visible ? contentHeight : 0
text: statusListItem.tertiaryTitle
@@ -356,24 +317,16 @@ Rectangle {
implicitHeight: visible ? 22 : 0
}
ScrollView {
visible: tagsRepeater.count > 0
Row {
id: statusListItemTagsSlotInline
anchors.top: statusListItemTertiaryTitle.bottom
anchors.topMargin: visible? 8 : 0
width: parent.width
height: visible? contentHeight + 12 : contentHeight
spacing: 10
clip: true
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
Row {
id: statusListItemTagsSlotInline
spacing: 10
Repeater {
id: tagsRepeater
delegate: tagsDelegate
}
Repeater {
model: tagsModel
delegate: tagsDelegate
}
}
}
@@ -398,7 +351,7 @@ Rectangle {
id: statusListItemLabel
anchors.verticalCenter: bottomModel.length === 0 ? parent.verticalCenter : undefined
anchors.top: bottomModel.length === 0 ? undefined: parent.top
anchors.topMargin: bottomModel.length === 0 ? 0 : 16
anchors.topMargin: bottomModel.length === 0 ? undefined : 16
anchors.right: statusListItemComponentsSlot.left
anchors.rightMargin: statusListItemComponentsSlot.width > 0 ? 10 : 0
+18 -13
View File
@@ -13,12 +13,17 @@ Control {
property string primaryText: ""
property string secondaryText: ""
property StatusAssetSettings asset: StatusAssetSettings {
property StatusImageSettings image: StatusImageSettings {
height: 16
width: 16
isIdenticon: false
}
property StatusIconSettings icon: StatusIconSettings {
height: 16
width: 16
isLetterIdenticon: false
background: StatusIconBackgroundSettings {}
color: "transparent"
imgIsIdenticon: false
}
background: Rectangle {
@@ -38,22 +43,22 @@ Control {
anchors.horizontalCenterOffset: -spacing
spacing: 2
StatusRoundedImage {
implicitWidth: root.asset.width
implicitHeight: root.asset.height
visible: !root.asset.isLetterIdenticon
image.source: root.asset.name
implicitWidth: root.image.width
implicitHeight: root.image.height
visible: !root.icon.isLetterIdenticon
image.source: root.image.source
border.color: Theme.palette.baseColor1
border.width: root.asset.imgIsIdenticon ? 1 : 0
border.width: root.image.isIdenticon ? 1 : 0
}
StatusLetterIdenticon {
implicitWidth: root.asset.width
implicitHeight: root.asset.width
implicitWidth: root.icon.width
implicitHeight: root.icon.width
letterSize: 11
visible: root.asset.isLetterIdenticon
color: root.asset.color
visible: root.icon.isLetterIdenticon
color: root.icon.color
name: root.primaryText
emoji: root.asset.emoji
emojiSize: root.asset.emojiSize
emoji: root.icon.emoji
emojiSize: root.icon.emojiSize
}
StatusBaseText {
font.weight: Font.Medium
+23 -12
View File
@@ -6,8 +6,8 @@ import StatusQ.Core.Theme 0.1
Rectangle {
id: root
implicitWidth: layout.width + layout.anchors.margins
implicitHeight: 30
width: layout.width + layout.anchors.margins
height: 30
color: Theme.palette.primaryColor3
radius: 15
@@ -15,19 +15,26 @@ Rectangle {
property string title: ""
property bool closeButtonVisible: true
signal clicked(var mouse)
signal clicked()
property StatusAssetSettings asset: StatusAssetSettings {
property StatusImageSettings image: StatusImageSettings {
width: 20
height: 20
isIdenticon: false
}
property StatusIconSettings icon: StatusIconSettings {
height: 20
width: 20
rotation: 0
isLetterIdenticon: false
letterSize: 10
color: Theme.palette.primaryColor1
bgWidth: 15
bgHeight: 15
bgColor: Theme.palette.primaryColor3
imgIsIdenticon: false
background: StatusIconBackgroundSettings {
width: 15
height: 15
color: Theme.palette.primaryColor3
}
}
RowLayout {
@@ -38,10 +45,12 @@ Rectangle {
StatusSmartIdenticon {
id: iconOrImage
Layout.leftMargin: 4
asset: root.asset
image: root.image
icon: root.icon
name: root.title
active: root.asset.isLetterIdenticon ||
!!root.asset.name
active: root.icon.isLetterIdenticon ||
!!root.icon.name ||
!!root.image.source.toString()
}
StatusBaseText {
@@ -61,7 +70,9 @@ Rectangle {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: root.clicked(mouse)
onClicked: {
root.clicked()
}
}
}
}
+4 -4
View File
@@ -294,7 +294,7 @@ Item {
bottomPadding: 0
placeholderText: root.placeholderSearchText
text: root.searchText
input.asset.name: "search"
input.icon.name: "search"
onTextChanged: root.searchText = text
}
@@ -303,11 +303,11 @@ Item {
width: content.itemWidth
height: content.itemHeight
color: mouseArea.containsMouse ? Theme.palette.baseColor4 : "transparent"
asset: StatusAssetSettings {
name: root.proxy.imageSource(model) ? root.proxy.imageSource(model) : ""
image: StatusImageSettings {
source: root.proxy.imageSource(model) ? root.proxy.imageSource(model) : ""
width: 15
height: 15
imgIsIdenticon: false
isIdenticon: false
}
name: root.proxy.name(model)
shortName: root.proxy.shortName(model)
@@ -120,6 +120,7 @@ StatusListItem {
}
subTitle: d.composeSubtitile()
statusListItemSubTitle.font.pixelSize: 10
icon.isLetterIdenticon: !root.image.source.toString()
statusListItemIcon.badge.visible: true
statusListItemIcon.badge.color: root.status === 1 ? Theme.palette.successColor1 : Theme.palette.baseColor1 // FIXME
color: sensor.containsMouse ? Theme.palette.baseColor2 : Theme.palette.baseColor4
@@ -128,8 +129,10 @@ StatusListItem {
implicitWidth: 256
implicitHeight: Math.max(56, statusListItemTitleArea.height + leftPadding)
leftPadding: 8
asset.width: 32
asset.height: 32
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
+84 -333
View File
@@ -1,16 +1,14 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import QtQuick.Controls 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Controls 0.1
import "./private/statusMessage"
Rectangle {
id: root
id: statusMessage
enum ContentType {
Unknown = 0,
@@ -23,12 +21,12 @@ Rectangle {
Invitation = 7
}
property alias quickActions: quickActionsPanel.items
property alias messageHeader: messageHeader
property alias quickActions:quickActionsPanel.quickActions
property alias statusChatInput: editComponent.inputComponent
property alias linksComponent: linksLoader.sourceComponent
property alias transcationComponent: transactionBubbleLoader.sourceComponent
property alias invitationComponent: invitationBubbleLoader.sourceComponent
property alias mouseArea: mouseArea
property alias footerComponent: footer.sourceComponent
property alias timestamp: messageHeader.timestamp
property string resendText: ""
property string cancelButtonText: ""
@@ -37,395 +35,155 @@ Rectangle {
property string errorLoadingImageText: ""
property string audioMessageInfoText: ""
property string pinnedMsgInfoText: ""
property string messageAttachments: ""
property var reactionIcons: [
Emoji.iconSource("❤"),
Emoji.iconSource("👍"),
Emoji.iconSource("👎"),
Emoji.iconSource("🤣"),
Emoji.iconSource("😥"),
Emoji.iconSource("😠")
]
property string messageId: ""
property bool isAppWindowActive: false
property bool editMode: false
property bool isAReply: false
property bool isEdited: false
property bool isChatBlocked: false
property bool hasMention: false
property bool isPinned: false
property string pinnedBy: ""
property bool hasExpired: false
property double timestamp: 0
property var reactionsModel: []
readonly property bool dateGroupVisible: dateGroupLabel.visible
property bool showHeader: true
property bool isActiveMessage: false
property bool disableHover: false
property bool hideQuickActions: false
property color overrideBackgroundColor: "transparent"
property bool overrideBackground: false
property bool profileClickable: true
property alias previousMessageIndex: dateGroupLabel.previousMessageIndex
property alias previousMessageTimestamp: dateGroupLabel.previousMessageTimestamp
property StatusMessageDetails messageDetails: StatusMessageDetails {}
property StatusMessageDetails replyDetails: StatusMessageDetails {}
property string timestampString: Qt.formatTime(new Date(timestamp), "hh:mm");
property string timestampTooltipString: Qt.formatTime(new Date(timestamp), "dddd, MMMM d, yyyy hh:mm:ss t");
signal clicked(var sender, var mouse)
signal profilePictureClicked(var sender, var mouse)
signal senderNameClicked(var sender, var mouse)
signal replyProfileClicked(var sender, var mouse)
signal addReactionClicked(var sender, var mouse)
signal toggleReactionClicked(int emojiId)
signal imageClicked(var image, var mouse, var imageSource)
signal stickerClicked()
signal profilePictureClicked()
signal senderNameClicked()
signal editCompleted(var newMsgText)
signal replyProfileClicked()
signal stickerLoaded()
signal imageClicked(var imageSource)
signal resendClicked()
signal editCompleted(var newMsgText)
signal editCancelled()
signal stickerLoaded()
signal linkActivated(string link)
signal hoverChanged(string messageId, bool hovered)
signal activeChanged(string messageId, bool active)
function startMessageFoundAnimation() {
messageFoundAnimation.start();
}
onMessageAttachmentsChanged: {
root.prepareAttachmentsModel()
}
function prepareAttachmentsModel() {
attachmentsModel.clear()
if (!root.messageAttachments) {
return
}
root.messageAttachments.split(" ").forEach(source => {
attachmentsModel.append({source})
})
}
implicitWidth: messageLayout.implicitWidth
+ messageLayout.anchors.leftMargin
+ messageLayout.anchors.rightMargin
implicitHeight: messageLayout.implicitHeight
+ messageLayout.anchors.topMargin
+ messageLayout.anchors.bottomMargin
color: {
if (root.overrideBackground)
return root.overrideBackgroundColor;
if (root.editMode)
return Theme.palette.baseColor2;
if (hoverHandler.hovered || root.isActiveMessage) {
if (root.hasMention)
return Theme.palette.mentionColor3;
if (root.isPinned)
return Theme.palette.pinColor2;
return Theme.palette.baseColor2;
}
if (root.hasMention)
return Theme.palette.mentionColor4;
if (root.isPinned)
return Theme.palette.pinColor3;
return "transparent";
}
Rectangle {
anchors {
top: parent.top
bottom: parent.bottom
left: parent.left
}
width: 2
visible: root.isPinned
color: Theme.palette.pinColor1
}
Rectangle {
anchors {
top: parent.top
bottom: parent.bottom
left: parent.left
}
width: 2
visible: root.hasMention
color: Theme.palette.mentionColor1
}
SequentialAnimation {
id: messageFoundAnimation
PauseAnimation {
duration: 600
}
NumberAnimation {
target: highlightRect
property: "opacity"
to: 1.0
duration: 1500
}
PauseAnimation {
duration: 1000
}
NumberAnimation {
target: highlightRect
property: "opacity"
to: 0.0
duration: 1500
}
}
Rectangle {
id: highlightRect
anchors.fill: parent
opacity: 0
visible: opacity > 0.001
color: Theme.palette.baseColor2
}
MouseArea {
id: mouseArea
anchors.fill: parent
}
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
enabled: !root.isActiveMessage && !root.disableHover
}
ColumnLayout {
id: messageLayout
anchors.fill: parent
anchors.topMargin: 8
anchors.bottomMargin: 8
StatusDateGroupLabel {
id: dateGroupLabel
width: parent.width
StatusMessageReply {
Layout.fillWidth: true
Layout.topMargin: 20
messageTimestamp: root.timestamp
visible: text !== ""
visible: isAReply
replyDetails: statusMessage.replyDetails
onReplyProfileClicked: statusMessage.replyProfileClicked()
audioMessageInfoText: statusMessage.audioMessageInfoText
}
Loader {
Layout.fillWidth: true
active: isAReply
visible: active
sourceComponent: StatusMessageReply {
replyDetails: root.replyDetails
profileClickable: root.profileClickable
onReplyProfileClicked: root.replyProfileClicked(sender, mouse)
audioMessageInfoText: root.audioMessageInfoText
}
}
RowLayout {
Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
spacing: 8
Item {
implicitWidth: root.messageDetails.sender.profileImage.assetSettings.width
implicitHeight: profileImage.visible ? profileImage.height : 0
Layout.fillWidth: true
StatusSmartIdenticon {
id: profileImage
Layout.alignment: Qt.AlignTop
StatusSmartIdenticon {
id: profileImage
active: root.showHeader
visible: active
name: root.messageDetails.sender.displayName
asset: root.messageDetails.sender.profileImage.assetSettings
ringSettings: root.messageDetails.sender.profileImage.ringSettings
MouseArea {
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
enabled: root.profileClickable
onClicked: root.profilePictureClicked(this, mouse)
}
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()
}
}
ColumnLayout {
Column {
spacing: 4
Layout.alignment: Qt.AlignTop
Layout.topMargin: 10
Layout.fillWidth: true
Loader {
active: root.isPinned && !editMode
visible: active
sourceComponent: StatusPinMessageDetails {
pinnedMsgInfoText: root.pinnedMsgInfoText
pinnedBy: root.pinnedBy
}
StatusPinMessageDetails {
visible: messageDetails.isPinned && !editMode
pinnedMsgInfoText: statusMessage.pinnedMsgInfoText
pinnedBy: messageDetails.pinnedBy
}
StatusMessageHeader {
Layout.fillWidth: true
sender: root.messageDetails.sender
amISender: root.messageDetails.amISender
messageOriginInfo: root.messageDetails.messageOriginInfo
resendText: root.resendText
showResendButton: root.hasExpired && root.messageDetails.amISender
onClicked: root.senderNameClicked(sender, mouse)
onResendClicked: root.resendClicked()
visible: root.showHeader && !editMode
timestamp.text: root.timestampString
timestamp.tooltip.text: root.timestampTooltipString
displayNameClickable: root.profileClickable
id: messageHeader
width: parent.width
displayName: messageDetails.displayName
secondaryName: messageDetails.secondaryName
tertiaryDetail: messageDetails.chatID
isContact: messageDetails.isContact
trustIndicator: messageDetails.trustIndicator
resendText: statusMessage.resendText
showResendButton: messageDetails.hasExpired && messageDetails.amISender
onClicked: statusMessage.senderNameClicked()
onResendClicked: statusMessage.resendClicked()
visible: !editMode
}
Loader {
Layout.fillWidth: true
active: !editMode && !!root.messageDetails.messageText
active: !editMode && !!messageDetails.messageText
width: parent.width
visible: active
sourceComponent: StatusTextMessage {
objectName: "StatusMessage_textMessage"
textField.text: {
if (root.messageDetails.contentType === StatusMessage.ContentType.Sticker)
return "";
const formattedMessage = Utils.linkifyAndXSS(root.messageDetails.messageText);
if (root.messageDetails.contentType === StatusMessage.ContentType.Emoji)
return Emoji.parse(formattedMessage, Emoji.size.middle, Emoji.format.png);
if (root.isEdited) {
const index = formattedMessage.endsWith("code>") ? formattedMessage.length : formattedMessage.length - 4;
const editedMessage = formattedMessage.slice(0, index)
+ ` <span class="isEdited">` + qsTr("(edited)") + `</span>`
+ formattedMessage.slice(index);
return Utils.getMessageWithStyle(Emoji.parse(editedMessage), textField.hoveredLink)
}
return Utils.getMessageWithStyle(Emoji.parse(formattedMessage), textField.hoveredLink)
}
onLinkActivated: {
root.linkActivated(link);
}
width: parent.width
textField.text: messageDetails.messageText
}
}
Loader {
active: root.messageDetails.contentType === StatusMessage.ContentType.Image && !editMode
active: messageDetails.contentType === StatusMessage.ContentType.Image && !editMode
visible: active
sourceComponent: StatusImageMessage {
source: root.messageDetails.contentType === StatusMessage.ContentType.Image ? root.messageDetails.messageContent : ""
onClicked: root.imageClicked(image, mouse, imageSource)
shapeType: root.messageDetails.amISender ? StatusImageMessage.ShapeType.RIGHT_ROUNDED : StatusImageMessage.ShapeType.LEFT_ROUNDED
source: messageDetails.contentType === StatusMessage.ContentType.Image ? messageDetails.messageContent : ""
onClicked: statusMessage.imageClicked()
shapeType: messageDetails.amISender ? StatusImageMessage.ShapeType.RIGHT_ROUNDED : StatusImageMessage.ShapeType.LEFT_ROUNDED
}
}
Loader {
active: !!root.messageAttachments && !editMode
visible: active
sourceComponent: Column {
spacing: 4
Layout.fillWidth: true
Repeater {
model: attachmentsModel
delegate: StatusImageMessage {
source: model.source
onClicked: root.imageClicked(image, mouse, imageSource)
shapeType: root.messageDetails.amISender ? StatusImageMessage.ShapeType.RIGHT_ROUNDED : StatusImageMessage.ShapeType.LEFT_ROUNDED
}
}
}
}
Loader {
active: root.messageDetails.contentType === StatusMessage.ContentType.Sticker && !editMode
visible: active
sourceComponent: StatusSticker {
asset.isImage: true
asset.name: root.messageDetails.messageContent
onLoaded: root.stickerLoaded()
onClicked: {
root.stickerClicked()
}
}
StatusSticker {
visible: messageDetails.contentType === StatusMessage.ContentType.Sticker && !editMode
image.source: messageDetails.messageContent
onLoaded: statusMessage.stickerLoaded()
}
Loader {
active: root.messageDetails.contentType === StatusMessage.ContentType.Audio && !editMode
active: messageDetails.contentType === StatusMessage.ContentType.Audio && !editMode
visible: active
sourceComponent: StatusAudioMessage {
audioSource: root.messageDetails.messageContent
audioSource: messageDetails.messageContent
hovered: hoverHandler.hovered
audioMessageInfoText: root.audioMessageInfoText
audioMessageInfoText: statusMessage.audioMessageInfoText
}
}
Loader {
id: linksLoader
active: !root.editMode
active: !!linksLoader.sourceComponent
visible: active
}
Loader {
id: transactionBubbleLoader
active: root.messageDetails.contentType === StatusMessage.ContentType.Transaction && !editMode
active: messageDetails.contentType === StatusMessage.ContentType.Transaction && !editMode
visible: active
}
Loader {
id: invitationBubbleLoader
active: root.messageDetails.contentType === StatusMessage.ContentType.Invitation && !editMode
active: messageDetails.contentType === StatusMessage.ContentType.Invitation && !editMode
visible: active
}
StatusEditMessage {
id: editComponent
Layout.fillWidth: true
Layout.rightMargin: 16
active: root.editMode
visible: active
msgText: root.messageDetails.messageText
saveButtonText: root.saveButtonText
cancelButtonText: root.cancelButtonText
onEditCancelled: root.editCancelled()
onEditCompleted: root.editCompleted(newMsgText)
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: root.resendText
text: statusMessage.resendText
font.pixelSize: 12
visible: root.hasExpired && root.messageDetails.amISender && !root.timestamp && !editMode
visible: messageDetails.hasExpired && messageDetails.amISender && !messageDetails.timestamp && !editMode
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: root.resendClicked()
onClicked: statusMessage.resendClicked()
}
}
Loader {
active: root.reactionsModel.count > 0
id: footer
active: sourceComponent && !editMode
visible: active
sourceComponent: StatusMessageEmojiReactions {
id: emojiReactionsPanel
emojiReactionsModel: root.reactionsModel
store: root.messageStore
icons: root.reactionIcons
onHoverChanged: {
root.hoverChanged(messageId, hovered)
}
isCurrentUser: root.messageDetails.amISender
onAddEmojiClicked: root.addReactionClicked(sender, mouse)
onToggleReaction: root.toggleReactionClicked(emojiID)
}
}
}
}
@@ -437,13 +195,6 @@ Rectangle {
anchors.rightMargin: 20
anchors.top: parent.top
anchors.topMargin: -8
visible: hoverHandler.hovered && !root.hideQuickActions
}
ListModel {
id: attachmentsModel
Component.onCompleted: {
root.prepareAttachmentsModel()
}
visible: hoverHandler.hovered && !editMode
}
}
@@ -6,10 +6,24 @@ QtObject {
id: msgDetails
property bool amISender: false
property StatusMessageSenderDetails sender: StatusMessageSenderDetails { }
property string displayName: ""
property string secondaryName: ""
property string chatID: ""
property StatusImageSettings profileImage: StatusImageSettings {
width: 40
height: 40
}
property bool isEdited: false
property int contentType: 0
property string messageText: ""
property int contentType: 0
property string messageContent: ""
property string messageOriginInfo: ""
property bool isContact: false
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
property bool hasMention: false
property bool isPinned: false
property string pinnedBy: ""
property bool hasExpired: false
property string timestamp: ""
}
@@ -1,21 +0,0 @@
import QtQuick 2.0
import StatusQ.Core 0.1
QtObject {
id: root
property string id: ""
property string displayName: ""
property string secondaryName: ""
property bool isEnsVerified: false
property bool isContact: false
property int trustIndicator: StatusContactVerificationIcons.TrustedType.None
property StatusProfileImageSettings profileImage: StatusProfileImageSettings {
pubkey: root.id
showRing: !root.isEnsVerified
width: 40
height: 40
}
}
@@ -12,9 +12,9 @@ StatusListItem {
implicitWidth: 286
implicitHeight: 48
asset.bgWidth: 20
asset.bgHeight: 20
asset.bgColor: "transparent"
icon.background.width: 20
icon.background.height: 20
icon.background.color: "transparent"
statusListItemIcon.anchors.topMargin: 14
+15 -13
View File
@@ -5,31 +5,33 @@ import StatusQ.Core.Theme 0.1
Rectangle {
id: statusRoundedIcon
property StatusAssetSettings asset: StatusAssetSettings {
property StatusIconSettings icon: StatusIconSettings {
width: 24
height: 24
rotation: 0
color: Theme.palette.primaryColor1
bgWidth: 40
bgHeight: 40
bgColor: Theme.palette.primaryColor3
background: StatusIconBackgroundSettings {
width: 40
height: 40
color: Theme.palette.primaryColor3
}
}
color: asset.bgColor
implicitWidth: asset.bgWidth
implicitHeight: asset.bgHeight
radius: asset.bgWidth / 2
color: icon.background.color
implicitWidth: icon.background.width
implicitHeight: icon.background.height
radius: icon.background.width / 2
StatusIcon {
id: statusIcon
anchors.centerIn: parent
width: statusRoundedIcon.asset.width
height: statusRoundedIcon.asset.height
width: statusRoundedIcon.icon.width
height: statusRoundedIcon.icon.height
color: statusRoundedIcon.asset.color
icon: statusRoundedIcon.asset.name
rotation: statusRoundedIcon.asset.rotation
color: statusRoundedIcon.icon.color
icon: statusRoundedIcon.icon.name
rotation: statusRoundedIcon.icon.rotation
}
}
+40 -37
View File
@@ -4,7 +4,7 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
Loader {
id: root
id: statusSmartIdenticon
property string name: ""
property int dZ: 100
@@ -12,46 +12,51 @@ Loader {
// Badge color properties must be set if badgeItem.visible = true
property alias badge: statusBadge
property StatusAssetSettings asset: StatusAssetSettings {
property StatusIconSettings icon: StatusIconSettings {
width: 40
height: 40
}
property StatusImageSettings image: StatusImageSettings {
width: 40
height: 40
}
property StatusIdenticonRingSettings ringSettings: StatusIdenticonRingSettings {
initalAngleRad: 0
ringPxSize: Math.max(1.5, root.asset.width/ 24.0)
ringPxSize: Math.max(1.5, statusSmartIdenticon.image.width / 24.0)
distinctiveColors: Theme.palette.identiconRingColors
}
sourceComponent: (root.asset.isLetterIdenticon || root.asset.name === "") ? letterIdenticon :
!root.asset.isImage ? roundedIcon : roundedImage
sourceComponent: statusSmartIdenticon.icon.isLetterIdenticon ? letterIdenticon :
!!statusSmartIdenticon.image.source.toString() ? roundedImage :
!!statusSmartIdenticon.icon.name.toString() ? roundedIcon : letterIdenticon
Component {
id: roundedImage
Item {
width: root.asset.width
height: root.asset.height
width: statusSmartIdenticon.image.width
height: statusSmartIdenticon.image.height
StatusRoundedImage {
id: statusRoundImage
width: parent.width
height: parent.height
image.source: root.asset.name
image.source: statusSmartIdenticon.image.source
showLoadingIndicator: true
border.width: root.asset.imgIsIdenticon ? 1 : 0
border.width: statusSmartIdenticon.image.isIdenticon ? 1 : 0
border.color: Theme.palette.directColor7
color: root.asset.imgIsIdenticon ?
color: statusSmartIdenticon.image.isIdenticon ?
Theme.palette.statusRoundedImage.backgroundColor :
"transparent"
}
Loader {
anchors.centerIn: parent
active: root.asset.imgStatus === Image.Error ||
statusRoundImage.image.status === Image.Error
active: statusRoundImage.image.status === Image.Error
sourceComponent: letterIdenticon
onLoaded: {
item.color = Theme.palette.miscColor5
item.width = root.asset.width
item.height = root.asset.height
item.width = statusSmartIdenticon.image.width
item.height = statusSmartIdenticon.image.height
}
}
}
@@ -60,14 +65,14 @@ Loader {
Component {
id: roundedIcon
StatusRoundIcon {
asset.bgWidth: root.asset.bgWidth
asset.bgHeight: root.asset.bgHeight
asset.bgColor: root.asset.bgColor
asset.width: root.asset.width
asset.height: root.asset.height
asset.name: root.asset.name
asset.rotation: root.asset.rotation
asset.color: root.asset.color
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
}
}
@@ -75,35 +80,33 @@ Loader {
id: letterIdenticon
StatusLetterIdenticon {
objectName: "statusSmartIdenticonLetter"
width: root.asset.width
height: root.asset.height
color: root.asset.color
name: root.name
emoji: root.asset.emoji
emojiSize: root.asset.emojiSize
letterSize: root.asset.letterSize
charactersLen: root.asset.charactersLen
width: statusSmartIdenticon.icon.width
height: statusSmartIdenticon.icon.height
color: statusSmartIdenticon.icon.color
name: statusSmartIdenticon.name
emoji: statusSmartIdenticon.icon.emoji
emojiSize: statusSmartIdenticon.icon.emojiSize
letterSize: statusSmartIdenticon.icon.letterSize
charactersLen: statusSmartIdenticon.icon.charactersLen
}
}
// Next components are painted above main sourceComponent
StatusIdenticonRing {
settings: root.ringSettings
settings: statusSmartIdenticon.ringSettings
anchors.fill: parent
z: root.dZ/2
z: statusSmartIdenticon.dZ/2
}
// State component
StatusBadge {
id: statusBadge
visible: false
anchors.bottom: root.bottom
anchors.right: root.right
anchors.rightMargin: -border.width
anchors.bottomMargin: -border.width
anchors.bottom: statusSmartIdenticon.bottom
anchors.right: statusSmartIdenticon.right
border.width: 3
implicitHeight: 15
implicitWidth: 15
z: root.dZ
z: statusSmartIdenticon.dZ
}
}
+5 -10
View File
@@ -180,7 +180,6 @@ Item {
"isContact": entry.isContact,
"ringSpecModel": entry.ringSpecModel,
"icon": entry.icon,
"isImage": entry.isImage,
"onlineStatus": entry.onlineStatus,
"tagIcon": entry.tagIcon ? entry.tagIcon : "",
"isReadonly": !!entry.isReadonly});
@@ -306,11 +305,8 @@ Item {
if ((event.key === Qt.Key_Backspace || event.key === Qt.Key_Escape)
&& getText(cursorPosition, (cursorPosition-1)) === ""
&& (namesList.count-1) >= 0) {
const item = namesModel.get(namesList.count-1)
if (!item.isReadonly) {
removeMember(item.pubKey);
namesModel.remove((namesList.count-1), 1);
}
removeMember(namesModel.get(namesList.count-1).pubKey);
namesModel.remove((namesList.count-1), 1);
}
if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && (sortedList.count > 0)) {
root.insertTag(sortedList.get(userListView.currentIndex).name,
@@ -416,10 +412,9 @@ Item {
isVerified: model.isVerified
isUntrustworthy: model.isUntrustworthy
isContact: model.isContact
asset.name: model.icon
asset.color: Theme.palette.userCustomizationColors[root.colorIdForPubkeyGetter(model.pubKey)]
asset.isImage: (asset.name !== "")
asset.isLetterIdenticon: (asset.name === "")
image.source: model.icon
image.isIdenticon: false
icon.color: Theme.palette.userCustomizationColors[root.colorIdForPubkeyGetter(model.pubKey)]
status: model.onlineStatus
statusListItemIcon.badge.border.color: sensor.containsMouse ? Theme.palette.baseColor2 : Theme.palette.baseColor4
ringSettings.ringSpecModel: root.ringSpecModelGetter(model.pubKey)
@@ -75,10 +75,10 @@ Control {
property int duration: 0
/*!
\qmlproperty StatusAssetSettings StatusToastMessage::icon
\qmlproperty StatusIconSettings StatusToastMessage::icon
This property holds a set of settings for the icon of the ToastMessage.
*/
property StatusAssetSettings icon: StatusAssetSettings {
property StatusIconSettings icon: StatusIconSettings {
width: 23
height: 23
}
-44
View File
@@ -1,44 +0,0 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
ToolBar {
id: root
property int notificationCount: 0
property Item headerContent
property alias notificationButton: notificationButton
signal notificationButtonClicked()
implicitWidth: visible ? 518 : 0
implicitHeight: visible ? 60 : 0
padding: 8
background: null
RowLayout {
anchors.fill: parent
spacing: 0
Control {
id: headerContentItem
Layout.fillWidth: !!headerContent
Layout.fillHeight: !!headerContent
background: null
contentItem: (!!headerContent) ? headerContent : null
}
Item {
Layout.fillWidth: !headerContent
}
StatusActivityCenterButton {
id: notificationButton
unreadNotificationsCount: root.notificationCount
onClicked: root.notificationButtonClicked()
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,139 +0,0 @@
/*!
* Elypson's Chart.qml adaptor to Chart.js
* (c) 2020 ChartJs2QML contributors (starting with Elypson, Michael A. Voelkel, https://github.com/Elypson)
* Released under the MIT License
*/
import QtQuick 2.13
import "Chart.js" as Chart
Canvas {
id: root
property var jsChart: undefined
property string chartType
property var chartData
property var chartOptions
property double chartAnimationProgress: 0.1
property var animationEasingType: Easing.InOutExpo
property double animationDuration: 500
property var memorizedContext
property var memorizedData
property var memorizedOptions
property alias animationRunning: chartAnimator.running
signal animationFinished()
function animateToNewData()
{
chartAnimationProgress = 0.1;
jsChart.update();
chartAnimator.restart();
}
MouseArea {
id: event
anchors.fill: root
hoverEnabled: true
enabled: true
property var handler: undefined
property QtObject mouseEvent: QtObject {
property int left: 0
property int top: 0
property int x: 0
property int y: 0
property int clientX: 0
property int clientY: 0
property string type: ""
property var target
}
function submitEvent(mouse, type) {
mouseEvent.type = type
mouseEvent.clientX = mouse ? mouse.x : 0;
mouseEvent.clientY = mouse ? mouse.y : 0;
mouseEvent.x = mouse ? mouse.x : 0;
mouseEvent.y = mouse ? mouse.y : 0;
mouseEvent.left = 0;
mouseEvent.top = 0;
mouseEvent.target = root;
if(handler) {
handler(mouseEvent);
}
root.requestPaint();
}
onClicked: {
submitEvent(mouse, "click");
}
onPositionChanged: {
submitEvent(mouse, "mousemove");
}
onExited: {
submitEvent(undefined, "mouseout");
}
onEntered: {
submitEvent(undefined, "mouseenter");
}
onPressed: {
submitEvent(mouse, "mousedown");
}
onReleased: {
submitEvent(mouse, "mouseup");
}
}
PropertyAnimation {
id: chartAnimator
target: root
property: "chartAnimationProgress"
alwaysRunToEnd: true
to: 1
duration: root.animationDuration
easing.type: root.animationEasingType
onFinished: {
root.animationFinished();
}
}
onChartAnimationProgressChanged: {
root.requestPaint();
}
onPaint: {
if(root.getContext('2d') != null && memorizedContext != root.getContext('2d') || memorizedData != root.chartData || memorizedOptions != root.chartOptions) {
var ctx = root.getContext('2d');
jsChart = new Chart.build(ctx, {
type: root.chartType,
data: root.chartData,
options: root.chartOptions
});
memorizedData = root.chartData ;
memorizedContext = root.getContext('2d');
memorizedOptions = root.chartOptions;
root.jsChart.bindEvents(function(newHandler) {event.handler = newHandler;});
chartAnimator.start();
}
jsChart.draw(chartAnimationProgress);
}
onWidthChanged: {
if(jsChart) {
jsChart.resize();
}
}
onHeightChanged: {
if(jsChart) {
jsChart.resize();
}
}
}
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2020 ChartJs2QML contributors (starting with Elypson, Michael A. Voelkel, https://github.com/Elypson)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -6,63 +6,45 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
Item {
id: root
id: editText
property alias inputComponent: chatInputLoader.sourceComponent
property alias active: chatInputLoader.active
property string cancelButtonText: ""
property string saveButtonText: ""
property string msgText: ""
signal editCancelled()
signal cancelEditClicked()
signal editCompleted(var newMsgText)
implicitHeight: layout.implicitHeight
implicitWidth: layout.implicitWidth
height: childrenRect.height
ColumnLayout {
id: layout
anchors.fill: parent
spacing: 4
Loader {
id: chatInputLoader
Layout.fillWidth: true
/*
NOTE: sourceComponent must have `messageText` property
TODO: Replace with StatusChatInput once its moved to StatusQ.
*/
// To-Do: Move to StatusChatInput once its moved to StatusQ
sourceComponent: StatusInput {
readonly property string messageText: input.text
width: parent.width
input.placeholderText: ""
width: editText.width
placeholderText: ""
input.text: msgText
maximumHeight: 40
}
}
RowLayout {
spacing: 4
StatusFlatButton {
id: cancelBtn
text: cancelButtonText
size: StatusBaseButton.Size.Small
onClicked: {
editCancelled()
}
onClicked: cancelEditClicked()
}
StatusButton {
id: saveBtn
text: saveButtonText
size: StatusBaseButton.Size.Small
enabled: !!chatInputLoader.item && chatInputLoader.item.messageText.trim().length > 0
onClicked: {
editCompleted(!chatInputLoader.item ? "" : chatInputLoader.item.messageText)
}
enabled: chatInputLoader.item.input.text.trim().length > 0
onClicked: editCompleted(chatInputLoader.item.input.text)
}
}
}
@@ -25,10 +25,10 @@ Item {
property string loadingImageText: ""
property string errorLoadingImageText: ""
signal clicked(var image, var mouse, var imageSource)
signal clicked(var image, var mouse)
implicitWidth: loadingImage.visible ? loadingImage.width : imageMessage.width
implicitHeight: loadingImage.visible ? loadingImage.height : imageMessage.paintedHeight
width: loadingImage.visible ? loadingImage.width : imageMessage.width
height: loadingImage.visible ? loadingImage.height : imageMessage.paintedHeight
QtObject {
id: _internal
@@ -87,7 +87,7 @@ Item {
_internal.pausePlaying = ! _internal.pausePlaying
return
}
imageContainer.clicked(imageMessage, mouse, imageMessage.source)
imageContainer.clicked(imageMessage, mouse)
}
}
}
@@ -1,191 +0,0 @@
import QtQuick 2.3
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.14
import QtGraphicalEffects 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
implicitHeight: 22
implicitWidth: childrenRect.width
property int imageMargin: 4
signal addEmojiClicked(var sender, var mouse)
signal hoverChanged(bool hovered)
signal toggleReaction(int emojiID)
property var store
property bool isCurrentUser
property var emojiReactionsModel
property var icons: []
QtObject {
id: d
function lastTwoItems(nodes) {
return nodes.join(qsTr(" and "));
}
function showReactionAuthors(jsonArrayOfUsersReactedWithThisEmoji, emojiId) {
const listOfUsers = JSON.parse(jsonArrayOfUsersReactedWithThisEmoji)
if (listOfUsers.error) {
console.error("error parsing users who reacted to a message, error: ", obj.error)
return
}
let author;
if (listOfUsers.length === 1) {
author = listOfUsers[0]
} else if (listOfUsers.length === 2) {
author = lastTwoItems(listOfUsers);
} else {
var leftNode = [];
var rightNode = [];
const maxReactions = 12
let maximum = Math.min(maxReactions, listOfUsers.length)
if (listOfUsers.length > maxReactions) {
leftNode = listOfUsers.slice(0, maxReactions);
rightNode = listOfUsers.slice(maxReactions, listOfUsers.length);
return (rightNode.length === 1) ?
lastTwoItems([leftNode.join(", "), rightNode[0]]) :
lastTwoItems([leftNode.join(", "), qsTr("%1 more").arg(rightNode.length)]);
}
leftNode = listOfUsers.slice(0, maximum - 1);
rightNode = listOfUsers.slice(maximum - 1, listOfUsers.length);
author = lastTwoItems([leftNode.join(", "), rightNode[0]])
}
return qsTr("%1 reacted with %2")
.arg(author)
.arg(Emoji.getEmojiFromId(emojiId));
}
}
Row {
spacing: root.imageMargin
Repeater {
id: reactionRepeater
width: childrenRect.width
model: root.emojiReactionsModel
Control {
id: reactionDelegate
topPadding: 2
bottomPadding: 2
leftPadding: 2
rightPadding: 6
background: Rectangle {
radius: 10
color: model.didIReactWithThisEmoji
? (reactionDelegate.hovered ? Theme.palette.statusMessage.emojiReactionActiveBackgroundHovered
: Theme.palette.statusMessage.emojiReactionActiveBackground)
: (reactionDelegate.hovered ? Theme.palette.statusMessage.emojiReactionBackgroundHovered
: Theme.palette.statusMessage.emojiReactionBackground)
// Rounded corner to cover one corner
Rectangle {
anchors.top: parent.top
anchors.left: parent.left
width: 10
height: 10
radius: 2
color: parent.color
}
}
contentItem: Row {
spacing: 4
StatusEmoji {
anchors.verticalCenter: parent.verticalCenter
width: 15
height: 15
source: {
if (model.emojiId >= 1 && model.emojiId <= root.icons.length)
return root.icons[model.emojiId - 1];
return "";
}
}
StatusBaseText {
anchors.verticalCenter: parent.verticalCenter
text: model.numberOfReactions
font.pixelSize: 12
color: model.didIReactWithThisEmoji ? Theme.palette.indirectColor1 : Theme.palette.directColor1
}
}
StatusToolTip {
visible: reactionDelegate.hovered
maxWidth: 400
text: d.showReactionAuthors(model.jsonArrayOfUsersReactedWithThisEmoji, model.emojiId)
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onEntered: {
root.hoverChanged(true)
}
onExited: {
root.hoverChanged(false)
}
onClicked: {
root.toggleReaction(model.emojiId)
}
}
}
}
Item {
width: addEmojiButton.width + addEmojiButton.anchors.leftMargin // there is more margin between the button and the emojis than between each emoji
height: addEmojiButton.height
StatusIcon {
id: addEmojiButton
readonly property bool isHovered: addEmojiButtonMouseArea.containsMouse
anchors.left: parent.left
anchors.leftMargin: 2.5
icon: "reaction-b"
width: 16.5
height: 16.5
color: addEmojiButton.isHovered ? Theme.palette.primaryColor1 : Theme.palette.baseColor1
}
MouseArea {
id: addEmojiButtonMouseArea
anchors.fill: addEmojiButton
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onClicked: {
root.addEmojiClicked(this, mouse);
}
}
StatusToolTip {
visible: addEmojiButton.isHovered
text: qsTr("Add reaction")
}
}
}
}
@@ -3,41 +3,36 @@ import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
Item {
id: root
property StatusMessageSenderDetails sender: StatusMessageSenderDetails { }
id: statusMessageHeader
property alias displayNameLabel: primaryDisplayName
property alias secondaryNameLabel: secondaryDisplayName
property alias tertiaryDetailsLabel: tertiaryDetailText
property alias timestamp: timestampText
property string tertiaryDetail: sender.id
property string displayName: ""
property string secondaryName: ""
property string tertiaryDetail: ""
property string resendText: ""
property bool showResendButton: false
property bool isContact: sender.isContact
property int trustIndicator: sender.trustIndicator
property bool amISender: false
property bool displayNameClickable: true
property string messageOriginInfo: ""
property bool isContact: false
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
signal clicked(var sender, var mouse)
signal clicked()
signal resendClicked()
implicitHeight: layout.implicitHeight
implicitWidth: layout.implicitWidth
height: childrenRect.height
width: primaryDisplayName.width + (secondaryDisplayName.visible ? secondaryDisplayName.width + header.spacing : 0)
RowLayout {
id: layout
id: header
spacing: 4
TextEdit {
id: primaryDisplayName
Layout.alignment: Qt.AlignBottom
font.family: Theme.palette.baseFont.name
font.weight: Font.Medium
font.pixelSize: 15
@@ -46,62 +41,55 @@ Item {
wrapMode: Text.WordWrap
selectByMouse: true
color: Theme.palette.primaryColor1
text: root.amISender ? qsTr("You") : root.sender.displayName
text: displayName
MouseArea {
id: mouseArea
anchors.fill: parent
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
enabled: root.displayNameClickable
hoverEnabled: true
onClicked: {
root.clicked(this, mouse)
statusMessageHeader.clicked()
}
}
Layout.alignment: Qt.AlignBottom
}
StatusBaseText {
id: messageOriginInfo
Layout.alignment: Qt.AlignVCenter
visible: root.messageOriginInfo !== ""
color: Theme.palette.baseColor1
font.pixelSize: 10
text: root.messageOriginInfo
}
StatusContactVerificationIcons {
visible: !root.amISender
isContact: root.isContact
trustIndicator: root.trustIndicator
isContact: statusMessageHeader.isContact
trustIndicator: statusMessageHeader.trustIndicator
}
StatusBaseText {
id: secondaryDisplayName
Layout.alignment: Qt.AlignVCenter
visible: !root.amISender && !!root.sender.secondaryName
color: Theme.palette.baseColor1
font.pixelSize: 10
text: `(${root.sender.secondaryName})`
text: secondaryName
visible: !!text
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
visible: secondaryDisplayName.visible
id: dotSeparator1
Layout.fillHeight: true
font.pixelSize: 10
color: Theme.palette.baseColor1
text: ""
text: "."
visible: secondaryDisplayName.visible
}
StatusBaseText {
id: tertiaryDetailText
visible: !root.amISender && root.messageOriginInfo === ""
Layout.alignment: Qt.AlignVCenter
Layout.maximumWidth: 58
font.pixelSize: 10
elide: Text.ElideMiddle
color: Theme.palette.baseColor1
text: Utils.elideText(tertiaryDetail, 5, 3)
text: tertiaryDetail
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
visible: tertiaryDetailText.visible
id: dotSeparator2
Layout.fillHeight: true
font.pixelSize: 10
color: Theme.palette.baseColor1
text: ""
text: "."
visible: tertiaryDetailText.visible
}
StatusTimeStampLabel {
id: timestampText
@@ -110,12 +98,12 @@ Item {
Layout.alignment: Qt.AlignVCenter
color: Theme.palette.dangerColor1
font.pixelSize: 12
text: root.resendText
text: statusMessageHeader.resendText
visible: showResendButton && !!timestampText.text
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: root.resendClicked()
onClicked: statusMessageHeader.resendClicked()
}
}
}
@@ -6,29 +6,29 @@ import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
Rectangle {
id: root
id: buttonsContainer
property list<Item> items
property list<Item> quickActions
QtObject {
id: _internal
readonly property int containerMargin: 2
}
implicitWidth: buttonRow.width + _internal.containerMargin * 2
implicitHeight: 36
width: buttonRow.width + _internal.containerMargin * 2
height: 36
radius: 8
color: Theme.palette.statusSelect.menuItemBackgroundColor
layer.enabled: true
layer.effect: DropShadow {
width: root.width
height: root.height
x: root.x
y: root.y + 10
width: buttonsContainer.width
height: buttonsContainer.height
x: buttonsContainer.x
y: buttonsContainer.y + 10
horizontalOffset: 0
verticalOffset: 2
source: root
source: buttonsContainer
radius: 10
samples: 15
color: Theme.palette.dropShadow
@@ -39,13 +39,13 @@ Rectangle {
spacing: _internal.containerMargin
anchors.left: parent.left
anchors.leftMargin: _internal.containerMargin
anchors.verticalCenter: root.verticalCenter
anchors.verticalCenter: buttonsContainer.verticalCenter
height: parent.height - 2 * _internal.containerMargin
}
onItemsChanged: {
for (let idx in items) {
items[idx].parent = buttonRow
onQuickActionsChanged: {
for (let idx in quickActions) {
quickActions[idx].parent = buttonRow
}
}
}
@@ -7,20 +7,18 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
Item {
id: root
Loader {
id: chatReply
property StatusMessageDetails replyDetails
property string audioMessageInfoText: ""
property bool profileClickable: true
signal replyProfileClicked(var sender, var mouse)
signal replyProfileClicked()
implicitHeight: layout.implicitHeight
implicitWidth: layout.implicitWidth
active: visible
RowLayout {
id: layout
sourceComponent: RowLayout {
id: replyLayout
spacing: 8
Shape {
id: replyCorner
@@ -58,15 +56,13 @@ Item {
StatusSmartIdenticon {
id: profileImage
Layout.alignment: Qt.AlignTop
name: replyDetails.sender.displayName
asset: replyDetails.sender.profileImage.assetSettings
ringSettings: replyDetails.sender.profileImage.ringSettings
image: replyDetails.profileImage
name: replyDetails.displayName
MouseArea {
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
enabled: root.profileClickable
onClicked: replyProfileClicked(this, mouse)
onClicked: replyProfileClicked()
}
}
TextEdit {
@@ -78,7 +74,7 @@ Item {
font.weight: Font.Medium
selectByMouse: true
readOnly: true
text: replyDetails.amISender ? qsTr("You") : replyDetails.sender.displayName
text: replyDetails.displayName
}
}
StatusTextMessage {
@@ -89,14 +85,13 @@ Item {
textField.height: 18
clip: true
visible: !!replyDetails.messageText
allowShowMore: false
}
StatusImageMessage {
Layout.fillWidth: true
Layout.preferredHeight: imageAlias.paintedHeight
imageWidth: 56
source: replyDetails.contentType === StatusMessage.ContentType.Image ? replyDetails.messageContent : ""
// visible: replyDetails.contentType === StatusMessage.ContentType.Image
visible: replyDetails.contentType === StatusMessage.ContentType.Image
shapeType: StatusImageMessage.ShapeType.ROUNDED
}
Item {
@@ -105,10 +100,9 @@ Item {
Layout.alignment: Qt.AlignLeft
visible: replyDetails.contentType === StatusMessage.ContentType.Sticker
StatusSticker {
asset.width: 48
asset.height: 48
asset.name: replyDetails.messageContent
asset.isImage: true
image.width: 48
image.height: 48
image.source: replyDetails.messageContent
}
}
Item {
@@ -122,7 +116,7 @@ Item {
height: 22
isPreview: true
audioSource: replyDetails.messageContent
audioMessageInfoText: root.audioMessageInfoText
audioMessageInfoText: chatReply.audioMessageInfoText
}
}
}
@@ -1,5 +1,4 @@
import QtQuick 2.13
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import QtGraphicalEffects 1.13
@@ -12,35 +11,14 @@ Loader {
active: visible
sourceComponent: Control {
verticalPadding: 3
leftPadding: 2
rightPadding: 6
background: Rectangle {
readonly property color translucentColor: Theme.palette.pinColor2
implicitWidth: 24
implicitHeight: 24
color: Qt.rgba(translucentColor.r,
translucentColor.g,
translucentColor.b, 1)
opacity: translucentColor.a
layer.enabled: true
radius: 12
Rectangle {
anchors.bottom: parent.bottom
anchors.left: parent.left
width: parent.width / 2
height: parent.height / 2
color: parent.color
radius: 4
}
}
contentItem: RowLayout {
spacing: 4
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
@@ -57,6 +35,7 @@ Loader {
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
Layout.leftMargin: -4
color: Theme.palette.directColor1
font.pixelSize: 13
font.weight: Font.Medium
@@ -10,7 +10,7 @@ Loader {
property bool noHover: false
property bool noMouseArea: false
property StatusAssetSettings asset: StatusAssetSettings {
property StatusImageSettings image: StatusImageSettings {
width: 140
height: 140
}
@@ -26,8 +26,8 @@ Loader {
color: Theme.palette.baseColor2
radius: 16
width: asset.width
height: asset.height
width: image.width
height: image.height
function reload() {
// From the documentation (https://doc.qt.io/qt-5/qml-qtquick-image.html#sourceSize-prop)
@@ -53,7 +53,7 @@ Loader {
horizontalAlignment: Image.AlignHCenter
verticalAlignment: Image.AlignVCenter
cache: true
source: asset.name
source: image.source
onStatusChanged: {
if (status === Image.Ready) {
@@ -6,34 +6,24 @@ import StatusQ.Controls 0.1
import StatusQ.Core.Theme 0.1
Item {
id: root
id: textMessage
property int contentType: 0
property alias textField: chatText
property bool allowShowMore: true
signal linkActivated(string link)
signal linkActivated(url link)
implicitWidth: chatText.implicitWidth
implicitHeight: chatText.effectiveHeight + d.showMoreHeight
implicitHeight: showMoreLoader.active ? childrenRect.height : chatText.height
QtObject {
id: d
id: _internal
property bool readMore: false
readonly property bool veryLongChatText: chatText.length > 1000
readonly property int showMoreHeight: showMoreLoader.visible ? showMoreLoader.height : 0
property bool veryLongChatText: chatText.length > 1000
}
TextEdit {
id: chatText
objectName: "StatusTextMessage_chatText"
readonly property int effectiveHeight: d.veryLongChatText && !d.readMore ? Math.min(chatText.implicitHeight, 200)
: chatText.implicitHeight
width: parent.width
height: effectiveHeight + d.showMoreHeight / 2
visible: !opMask.active
clip: true
visible: !showMoreLoader.active || _internal.readMore
selectedTextColor: Theme.palette.directColor1
selectionColor: Theme.palette.primaryColor3
color: Theme.palette.directColor1
@@ -43,12 +33,12 @@ Item {
wrapMode: Text.Wrap
readOnly: true
selectByMouse: true
onLinkActivated: {
root.linkActivated(link);
}
height: _internal.veryLongChatText && !_internal.readMore ? Math.min(implicitHeight, 200) : implicitHeight
width: parent.width
clip: height < implicitHeight
onLinkActivated: textMessage.linkActivated(link)
onLinkHovered: {
// Strange thing. Without this empty stub the cursorShape
// is not changed to pointingHandCursor.
cursorShape: Qt.PointingHandCursor
}
}
@@ -70,7 +60,7 @@ Item {
Loader {
id: opMask
active: showMoreLoader.active && !d.readMore
active: showMoreLoader.active && !_internal.readMore
anchors.fill: chatText
sourceComponent: OpacityMask {
source: chatText
@@ -80,17 +70,17 @@ Item {
Loader {
id: showMoreLoader
active: root.allowShowMore && d.veryLongChatText
visible: active
anchors.verticalCenter: chatText.bottom
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: d.readMore ? "chevron-up": "chevron-down"
icon.name: _internal.readMore ? "chevron-up": "chevron-down"
onClicked: {
d.readMore = !d.readMore
_internal.readMore = !_internal.readMore
}
}
}
+1 -5
View File
@@ -9,11 +9,10 @@ StatusChatListItem 0.1 StatusChatListItem.qml
StatusChatListCategory 0.1 StatusChatListCategory.qml
StatusChatListCategoryItem 0.1 StatusChatListCategoryItem.qml
StatusChatListAndCategories 0.1 StatusChatListAndCategories.qml
StatusToolBar 0.1 StatusToolBar.qml
StatusChatToolBar 0.1 StatusChatToolBar.qml
StatusContactRequestsIndicatorListItem 0.1 StatusContactRequestsIndicatorListItem.qml
StatusEmoji 0.1 StatusEmoji.qml
StatusContactVerificationIcons 0.1 StatusContactVerificationIcons.qml
StatusDateGroupLabel 0.1 StatusDateGroupLabel.qml
StatusDescriptionListItem 0.1 StatusDescriptionListItem.qml
StatusLetterIdenticon 0.1 StatusLetterIdenticon.qml
StatusListItem 0.1 StatusListItem.qml
@@ -32,7 +31,6 @@ StatusExpandableItem 0.1 StatusExpandableItem.qml
StatusSmartIdenticon 0.1 StatusSmartIdenticon.qml
StatusMessage 0.1 StatusMessage.qml
StatusMessageDetails 0.1 StatusMessageDetails.qml
StatusMessageSenderDetails 0.1 StatusMessageSenderDetails.qml
StatusTagSelector 0.1 StatusTagSelector.qml
StatusToastMessage 0.1 StatusToastMessage.qml
StatusWizardStepper 0.1 StatusWizardStepper.qml
@@ -43,5 +41,3 @@ StatusCommunityTags 0.1 StatusCommunityTags.qml
StatusItemSelector 0.1 StatusItemSelector.qml
StatusCard 0.1 StatusCard.qml
StatusDatePicker 0.1 StatusDatePicker.qml
StatusChart 0.1 StatusChart.qml
StatusChartPanel 0.1 StatusChartPanel.qml
+144 -94
View File
@@ -1,14 +1,11 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import QtQuick.Controls 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Core.Utils 0.1
Button {
id: root
Rectangle {
id: statusBaseButton
enum Size {
Tiny,
@@ -22,105 +19,158 @@ Button {
Primary
}
property StatusAssetSettings asset: StatusAssetSettings { }
property StatusIconSettings icon: StatusIconSettings {
width: 24
height: 24
}
property bool loading
property bool loading: false
property color normalColor
property color hoverColor
property color disabledColor
property color textColor
property color disabledTextColor
property color borderColor: "transparent"
property alias hovered: sensor.containsMouse
property int size: StatusBaseButton.Size.Large
property int type: StatusBaseButton.Type.Normal
property alias text: label.text
property alias font: label.font
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
case StatusBaseButton.Size.Large:
default:
return 11
}
}
property real defaultBottomPadding: {
switch (size) {
case StatusBaseButton.Size.Tiny:
return 5
case StatusBaseButton.Size.Small:
return 10
case StatusBaseButton.Size.Large:
default:
return 11
}
}
property real leftPadding: defaultLeftPadding
property real rightPadding: defaultRightPadding
property real topPadding: defaultTopPadding
property real bottomPadding: defaultBottomPadding
property color normalColor
property color hoverColor
property color disaledColor
property color textColor
property color disabledTextColor
signal pressed(var mouse)
signal released(var mouse)
signal clicked(var mouse)
signal pressAndHold(var mouse)
property bool highlighted: false
/// Implementation
implicitWidth: layout.width + statusBaseButton.leftPadding + statusBaseButton.rightPadding
implicitHeight: layout.height + statusBaseButton.topPadding + statusBaseButton.bottomPadding
radius: size !== StatusBaseButton.Size.Tiny ? 8 : 6
color: {
if (statusBaseButton.enabled)
return sensor.containsMouse || highlighted ? hoverColor
: normalColor;
return disaledColor
}
QtObject {
id: d
readonly property color textColor: root.enabled || root.loading ? root.textColor : root.disabledTextColor
readonly property color textColor: statusBaseButton.enabled ? statusBaseButton.textColor : statusBaseButton.disabledTextColor
}
font.weight: Font.Medium
font.pixelSize: size === StatusBaseButton.Size.Large ? 15 : 13
horizontalPadding: {
if (root.icon.name) {
return size === StatusBaseButton.Size.Large ? 18 : 16
}
return size === StatusBaseButton.Size.Large ? 24 : 12
}
verticalPadding: {
switch (size) {
case StatusBaseButton.Size.Tiny:
return 5
case StatusBaseButton.Size.Small:
return 10
case StatusBaseButton.Size.Large:
default:
return 11
}
}
spacing: root.size === StatusBaseButton.Size.Large ? 6 : 4
icon.height: 24
icon.width: 24
background: Rectangle {
radius: root.size === StatusBaseButton.Size.Tiny ? 6 : 8
border.color: root.borderColor
color: {
if (root.enabled)
return !root.loading && (root.hovered || root.highlighted) ? hoverColor : normalColor;
return disabledColor;
}
}
contentItem: RowLayout {
spacing: root.spacing
StatusIcon {
Layout.preferredWidth: visible ? root.icon.width : 0
Layout.preferredHeight: visible ? root.icon.height : 0
icon: root.icon.name
rotation: root.asset.rotation
opacity: !loading && root.icon.name !== ""
visible: root.icon.name !== ""
color: d.textColor
}
StatusEmoji {
Layout.preferredWidth: visible ? root.icon.width : 0
Layout.preferredHeight: visible ? root.icon.height : 0
visible: root.asset.emoji
emojiId: Emoji.iconId(root.asset.emoji, root.asset.emojiSize) || ""
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
opacity: !loading
font: root.font
text: root.text
color: d.textColor
verticalAlignment: Text.AlignVCenter
}
}
Loader {
anchors.centerIn: parent
active: root.loading
sourceComponent: StatusLoadingIndicator {
color: d.textColor
}
}
// stop the mouse clicks in the "loading" state w/o disabling the whole button
// as this would make it impossible to have hover events or a tooltip
MouseArea {
id: sensor
anchors.fill: parent
acceptedButtons: Qt.AllButtons
enabled: root.loading
onPressed: mouse.accepted = true
onWheel: wheel.accepted = true
cursorShape: !root.loading ? Qt.PointingHandCursor: undefined // always works; 'undefined' resets to default cursor
}
cursorShape: loading ? Qt.ArrowCursor
: Qt.PointingHandCursor
hoverEnabled: true
enabled: !loading && statusBaseButton.enabled
Loader {
anchors.centerIn: parent
active: loading
sourceComponent: StatusLoadingIndicator {
color: d.textColor
} // Indicator
} // Loader
Row {
id: layout
anchors.centerIn: parent
spacing: 4
StatusIcon {
id: statusIcon
width: statusBaseButton.icon.width
height: statusBaseButton.icon.height
icon: statusBaseButton.icon.name
rotation: statusBaseButton.icon.rotation
anchors.verticalCenter: parent.verticalCenter
opacity: !loading && statusBaseButton.icon.name !== ""
visible: statusBaseButton.icon.name !== ""
color: d.textColor
} // Icon
StatusEmoji {
width: statusBaseButton.icon.width
height: statusBaseButton.icon.height
anchors.verticalCenter: parent.verticalCenter
visible: statusBaseButton.icon.emoji
emojiId: Emoji.iconId(statusBaseButton.icon.emoji, statusBaseButton.icon.emojiSize) || ""
} // Emoji
StatusBaseText {
id: label
opacity: !loading
anchors.verticalCenter: parent.verticalCenter
font.pixelSize: size === StatusBaseButton.Size.Large ? 15 : 13 // by design
color: d.textColor
} // Text
} // Row
onPressed: {
if (!loading) {
statusBaseButton.pressed(mouse)
}
}
onReleased: {
if (!loading) {
statusBaseButton.released(mouse)
}
}
onClicked: {
if (!loading) {
statusBaseButton.clicked(mouse)
}
}
onPressAndHold: {
if (!loading) {
statusBaseButton.pressAndHold(mouse)
}
}
} // Sensor
}
+37 -27
View File
@@ -7,7 +7,6 @@ import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
/*!
\qmltype StatusBaseInput
@@ -183,9 +182,9 @@ Item {
/*!
\qmlproperty bool StatusBaseInput::valid
This property sets the valid state. Default value is false.
This property sets the valid state. Default value is true.
*/
property bool valid: false
property bool valid: true
/*!
\qmlproperty bool StatusBaseInput::pristine
This property sets the pristine. Default value is true.
@@ -218,19 +217,21 @@ Item {
property bool showBackground: true
/*!
\qmlproperty StatusAssetSettings StatusBaseInput::icon
\qmlproperty StatusIconSettings StatusBaseInput::icon
This property holds a set of settings for the icon of the StatusBaseInput.
*/
property StatusAssetSettings asset: StatusAssetSettings {
property StatusIconSettings icon: StatusIconSettings {
width: 24
height: 24
name: ""
color: Theme.palette.baseColor1
emoji: ""
letterSize: emoji ? 11 : 14
bgWidth: 30
bgHeight: 30
bgColor: Theme.palette.indirectColor1
background: StatusIconBackgroundSettings {
width: 30
height: 30
color: Theme.palette.indirectColor1
}
}
/*!
@@ -316,8 +317,8 @@ Item {
sourceComponent: {
if (root.leftComponent) return root.leftComponent
if (!root.leftIcon) return undefined
if (root.asset.emoji || root.asset.isLetterIdenticon) return identiconComponent
if (root.asset.name) return isIconSelectable ? identiconComponent : iconComponent
if (root.icon.emoji || root.icon.isLetterIdenticon) return identiconComponent
if (root.icon.name) return isIconSelectable ? identiconComponent : iconComponent
return undefined
}
}
@@ -338,6 +339,17 @@ Item {
}
clip: true
function ensureVisible(r) {
if (contentX >= r.x)
contentX = r.x
else if (contentX + width <= r.x + r.width)
contentX = r.x + r.width - width
if (contentY >= r.y)
contentY = r.y
else if (contentY + height <= r.y + r.height)
contentY = r.y + r.height - height
}
TextEdit {
id: edit
property string previousText: text
@@ -362,7 +374,7 @@ Item {
edit.keyEvent = event.key
root.keyPressed(event);
}
onCursorRectangleChanged: Utils.ensureVisible(flick, cursorRectangle)
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
onActiveFocusChanged: if (root.pristine) root.pristine = false
onTextChanged: {
if (previousText === text) {
@@ -418,8 +430,8 @@ Item {
if (root.rightComponent) return root.rightComponent
if (root.clearable) return clearButton
if (root.leftIcon) return undefined
if (root.asset.emoji) return identiconComponent
if (root.asset.name) return isIconSelectable ? identiconComponent : iconComponent
if (root.icon.emoji) return identiconComponent
if (root.icon.name) return isIconSelectable ? identiconComponent : iconComponent
return undefined
}
}
@@ -453,16 +465,14 @@ Item {
StatusSmartIdenticon {
id: identicon
asset.width: 24
asset.height: 24
asset.bgWidth: root.asset.bgWidth
asset.bgHeight: root.asset.bgHeight
asset.bgColor: root.asset.bgColor
asset.color: root.asset.color
asset.letterSize: root.asset.letterSize
asset.emoji: root.asset.emoji
asset.name: !root.asset.emoji ? root.asset.name : ""
asset.isLetterIdenticon: root.asset.isLetterIdenticon
icon.width: 24
icon.height: 24
icon.background: root.icon.background
icon.color: root.icon.color
icon.letterSize: root.icon.letterSize
icon.emoji: root.icon.emoji
icon.name: !root.icon.emoji ? root.icon.name : ""
icon.isLetterIdenticon: root.icon.isLetterIdenticon
name: root.letterIconName
MouseArea {
@@ -482,10 +492,10 @@ Item {
StatusIcon {
id: statusIcon
icon: root.asset.name
width: root.asset.width
height: root.asset.height
color: root.asset.color
icon: root.icon.name
width: root.icon.width
height: root.icon.height
color: root.icon.color
}
}
}
+3 -1
View File
@@ -11,10 +11,12 @@ StatusBaseButton {
hoverColor: type === StatusBaseButton.Type.Primary ? Theme.palette.hoverColor(normalColor) :
type === StatusBaseButton.Type.Normal ? Theme.palette.primaryColor2
: Theme.palette.dangerColor2
disabledColor: Theme.palette.baseColor2
disaledColor: Theme.palette.baseColor2
textColor: type === StatusBaseButton.Type.Primary ? Theme.palette.white :
type === StatusBaseButton.Type.Normal ? Theme.palette.primaryColor1
: Theme.palette.dangerColor1
disabledTextColor: Theme.palette.baseColor1
font.weight: type === StatusBaseButton.Type.Primary ? Font.Medium : Font.Normal
}
@@ -16,9 +16,10 @@ Rectangle {
signal clicked(var mouse)
property StatusAssetSettings icon: StatusAssetSettings {
property StatusIconSettings icon: StatusIconSettings {
width: 24
height: 24
background: StatusIconBackgroundSettings {}
}
color: {
@@ -40,14 +41,14 @@ Rectangle {
}
StatusRoundIcon {
asset.name: root.icon.name
asset.width: root.icon.width
asset.height: root.icon.height
asset.rotation: root.icon.rotation
asset.color: Theme.palette.white
asset.bgWidth: 40
asset.bgHeight: 40
asset.bgColor: root.icon.color
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
+183 -144
View File
@@ -1,22 +1,29 @@
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
Button {
id: root
Rectangle {
id: statusChatInfoButton
objectName: "chatInfoButton"
property string title: text
property string subTitle
property bool muted
property int pinnedMessagesCount
implicitWidth: identicon.width +
Math.max(
statusChatInfoButtonTitle.anchors.leftMargin + statusChatInfoButtonTitle.implicitWidth,
statusChatInfoButtonTitle.anchors.leftMargin + statusChatInfoButtonSubTitle.implicitWidth
) + 8
implicitHeight: 48
property StatusAssetSettings asset: StatusAssetSettings {
property string title: ""
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
charactersLen: 2
@@ -25,7 +32,9 @@ Button {
property int type: StatusChatInfoButton.Type.PublicChat
property alias tooltip: statusToolTip
property alias sensor: sensor
signal clicked(var mouse)
signal pinnedMessagesCountClicked(var mouse)
signal unmute()
signal linkActivated(string link)
@@ -40,162 +49,192 @@ Button {
CommunityChat // 6
}
horizontalPadding: 4
verticalPadding: 2
spacing: 4
radius: 8
color: sensor.enabled && sensor.containsMouse ? Theme.palette.baseColor2 : "transparent"
background: Rectangle {
radius: 8
color: root.enabled && root.hovered ? Theme.palette.baseColor2 : "transparent"
MouseArea {
id: sensor
anchors.fill: parent
hoverEnabled: true
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: root.hovered ? Qt.PointingHandCursor : undefined
}
}
onClicked: statusChatInfoButton.clicked(mouse)
contentItem: RowLayout {
spacing: root.spacing
// identicon
StatusSmartIdenticon {
id: identicon
asset: root.asset
name: root.title
anchors.left: parent.left
anchors.leftMargin: 4
anchors.verticalCenter: parent.verticalCenter
image: statusChatInfoButton.image
icon: statusChatInfoButton.icon
name: statusChatInfoButton.title
}
// text
ColumnLayout {
Layout.fillWidth: true
spacing: 2
Item {
id: statusChatInfoButtonTitle
anchors.top: identicon.top
anchors.topMargin: statusChatInfoButtonSubTitle.visible ? 0 : 8
anchors.left: identicon.right
anchors.leftMargin: 8
// title
RowLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignLeading | Qt.AlignBottom
spacing: root.spacing
width: Math.min(parent.width - anchors.leftMargin
- identicon.width - identicon.anchors.leftMargin,
implicitWidth)
height: chatName.height
StatusIcon {
visible: root.type !== StatusChatInfoButton.Type.OneToOneChat
Layout.preferredWidth: 14
Layout.preferredHeight: 14
color: root.muted ? Theme.palette.baseColor1 : Theme.palette.directColor1
icon: {
switch (root.type) {
case StatusChatInfoButton.Type.PublicCat:
return "tiny/public-chat"
case StatusChatInfoButton.Type.GroupChat:
return "tiny/group"
case StatusChatInfoButton.Type.CommunityChat:
return "tiny/channel"
default:
return "tiny/public-chat"
}
}
}
implicitWidth: statusIcon.width + chatName.anchors.leftMargin + chatName.implicitWidth
+ mutedDelta
StatusBaseText {
objectName: "statusChatInfoButtonNameText"
Layout.fillWidth: true
elide: Text.ElideRight
text: root.type === StatusChatInfoButton.Type.PublicChat && !root.title.startsWith("#") ?
"#" + root.title
: root.title
color: root.muted ? Theme.palette.directColor5 : Theme.palette.directColor1
font.weight: Font.Medium
}
property real mutedDelta: mutedIcon.visible ? mutedIcon.width + 8 : 0
StatusIcon {
objectName: "mutedIcon"
Layout.preferredWidth: 13
Layout.preferredHeight: 13
icon: "tiny/muted"
color: mutedIconSensor.containsMouse ? Theme.palette.directColor1 : Theme.palette.baseColor1
visible: root.muted
StatusIcon {
id: statusIcon
anchors.top: parent.top
anchors.topMargin: -2
anchors.left: parent.left
MouseArea {
id: mutedIconSensor
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: root.unmute()
}
StatusToolTip {
id: statusToolTip
text: qsTr("Unmute")
visible: mutedIconSensor.containsMouse
orientation: StatusToolTip.Orientation.Bottom
y: parent.height + 12
visible: statusChatInfoButton.type !== StatusChatInfoButton.Type.OneToOneChat
width: visible ? 14 : 0
color: statusChatInfoButton.muted ? Theme.palette.baseColor1 : Theme.palette.directColor1
icon: {
switch (statusChatInfoButton.type) {
case StatusChatInfoButton.Type.PublicCat:
return "tiny/public-chat"
break;
case StatusChatInfoButton.Type.GroupChat:
return "tiny/group"
break;
case StatusChatInfoButton.Type.CommunityChat:
return "tiny/channel"
break;
default:
return "tiny/public-chat"
}
}
}
// subtitle
RowLayout {
id: subtitleRow
Layout.fillWidth: true
Layout.alignment: Qt.AlignLeading | Qt.AlignTop
Layout.rightMargin: 4
spacing: 0
StatusBaseText {
id: chatName
objectName: "statusChatInfoButtonNameText"
StatusSelectableText {
Layout.fillWidth: implicitWidth + separator.width + pinIcon.width + pinText.width > subtitleRow.width
text: root.subTitle
color: Theme.palette.baseColor1
font.pixelSize: 12
onLinkActivated: root.linkActivated(link)
anchors.left: statusIcon.visible ? statusIcon.right : parent.left
anchors.leftMargin: statusIcon.visible ? 1 : 0
anchors.top: parent.top
elide: Text.ElideRight
width: Math.min(implicitWidth, parent.width
- statusIcon.width
- statusChatInfoButtonTitle.mutedDelta)
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
}
StatusIcon {
objectName: "mutedIcon"
id: mutedIcon
anchors.left: chatName.right
anchors.leftMargin: 4
anchors.top: chatName.top
anchors.topMargin: -2
width: 13
icon: "tiny/muted"
color: mutedIconSensor.containsMouse ? Theme.palette.directColor1 : Theme.palette.baseColor1
visible: statusChatInfoButton.muted
MouseArea {
id: mutedIconSensor
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: statusChatInfoButton.unmute()
}
Rectangle {
id: separator
Layout.preferredHeight: 12
Layout.preferredWidth: 1
Layout.leftMargin: 4
Layout.rightMargin: 2
color: Theme.palette.directColor7
visible: root.subTitle && root.pinnedMessagesCount
StatusToolTip {
id: statusToolTip
text: "Unmute"
visible: mutedIconSensor.containsMouse
orientation: StatusToolTip.Orientation.Bottom
y: parent.height + 12
}
}
}
StatusIcon {
id: pinIcon
Layout.preferredHeight: 14
Layout.preferredWidth: 14
visible: root.pinnedMessagesCount > 0
icon: "pin"
color: Theme.palette.baseColor1
Item {
id: statusChatInfoButtonSubTitle
anchors.left: statusChatInfoButtonTitle.left
anchors.top: statusChatInfoButtonTitle.bottom
visible: !!statusChatInfoButton.subTitle || statusChatInfoButton.pinnedMessagesCount > 0
height: visible ? chatType.height : 0
width: Math.min(parent.width - statusChatInfoButtonTitle.anchors.leftMargin
- identicon.width - identicon.anchors.leftMargin - 8,
implicitWidth)
implicitWidth: chatType.implicitWidth + pinIconDelta + 8
property real pinIconDelta: pinIcon.visible ? pinIcon.width + pinIcon.anchors.leftMargin
+ divider.width + divider.anchors.leftMargin
: 0
StatusSelectableText {
id: chatType
text: statusChatInfoButton.subTitle
color: Theme.palette.baseColor1
font.pixelSize: 12
width: Math.min(parent.width - (pinIcon.visible ? divider.width + divider.anchors.leftMargin + pinIcon.width + pinIcon.anchors.leftMargin : 0),
implicitWidth)
onLinkActivated: statusChatInfoButton.linkActivated(link)
}
Rectangle {
id: divider
height: 12
width: 1
color: Theme.palette.directColor7
anchors.left: chatType.right
anchors.leftMargin: 4
anchors.verticalCenter: chatType.verticalCenter
visible: !!chatType.text && pinIcon.visible
}
StatusIcon {
id: pinIcon
anchors.left: divider.visible ? divider.right : parent.left
anchors.leftMargin: -2
anchors.verticalCenter: chatType.verticalCenter
height: 14
visible: statusChatInfoButton.pinnedMessagesCount > 0
icon: "pin"
color: Theme.palette.baseColor1
}
StatusBaseText {
anchors.left: pinIcon.right
anchors.leftMargin: -6
anchors.verticalCenter: pinIcon.verticalCenter
width: 14
text: statusChatInfoButton.pinnedMessagesCount
font.pixelSize: 12
font.underline: pinCountSensor.containsMouse
visible: pinIcon.visible
color: pinCountSensor.containsMouse ? Theme.palette.directColor1 : Theme.palette.baseColor1
MouseArea {
objectName: "pinMessagesCounterSensor"
id: pinCountSensor
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: statusChatInfoButton.pinnedMessagesCountClicked(mouse)
}
StatusBaseText {
id: pinText
TextMetrics {
id: tm
font: pinText.font
elide: Text.ElideRight
elideWidth: pinText.width
text: qsTr("%Ln pinned message(s)", "", root.pinnedMessagesCount)
}
objectName: "StatusChatInfo_pinText"
Layout.fillWidth: true
text: tm.elidedText !== tm.text ? root.pinnedMessagesCount : tm.text
font.pixelSize: 12
font.underline: pinCountSensor.containsMouse
visible: root.pinnedMessagesCount
color: pinCountSensor.containsMouse ? Theme.palette.directColor1 : Theme.palette.baseColor1
MouseArea {
objectName: "pinMessagesCounterSensor"
id: pinCountSensor
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: root.pinnedMessagesCountClicked(mouse)
}
}
Item { Layout.fillWidth: true }
}
}
}
+9 -15
View File
@@ -8,20 +8,16 @@ import StatusQ.Components 0.1
CheckBox {
id: root
property bool leftSide: true
id: statusCheckBox
indicator: Rectangle {
anchors.left: root.leftSide? parent.left : undefined
anchors.right: !root.leftSide? parent.right : undefined
implicitWidth: 18
implicitHeight: 18
x: !root.leftSide? root.rightPadding : root.leftPadding
x: statusCheckBox.leftPadding
y: parent.height / 2 - height / 2
radius: 2
color: (root.down || root.checked) ? Theme.palette.primaryColor1
: Theme.palette.directColor8
color: (statusCheckBox.down || statusCheckBox.checked) ? Theme.palette.primaryColor1
: Theme.palette.directColor8
StatusIcon {
icon: "checkbox"
@@ -30,21 +26,19 @@ CheckBox {
anchors.centerIn: parent
anchors.horizontalCenterOffset: 1
color: Theme.palette.white
visible: root.down || root.checked
visible: statusCheckBox.down || statusCheckBox.checked
}
}
contentItem: StatusBaseText {
text: root.text
font.pixelSize: root.font.pixelSize
text: statusCheckBox.text
font.pixelSize: statusCheckBox.font.pixelSize
opacity: enabled ? 1.0 : 0.3
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
width: parent.width
color: Theme.palette.directColor1
leftPadding: root.leftSide? (!!root.text ? root.indicator.width + root.spacing
: root.indicator.width) : 0
rightPadding: !root.leftSide? (!!root.text ? root.indicator.width + root.spacing
: root.indicator.width) : 0
leftPadding: !!statusCheckBox.text ? statusCheckBox.indicator.width + statusCheckBox.spacing
: statusCheckBox.indicator.width
}
}
@@ -8,13 +8,11 @@ RadioButton {
property string radioButtonColor: ""
property string selectionColor: StatusColors.colors['white']
property int diameter: 44
property int selectorDiameter: 16
property int diameter: 48
property int selectorDiameter: 20
spacing: 0
implicitWidth: 44
implicitHeight: 44
implicitWidth: 48
implicitHeight: 48
indicator: Rectangle {
implicitWidth: control.diameter
@@ -23,13 +21,13 @@ RadioButton {
color: radioButtonColor
Rectangle {
anchors.centerIn: parent
width: control.selectorDiameter
height: control.selectorDiameter
visible: control.checked
radius: width/2
color: selectionColor
border.color: StatusColors.colors['grey3']
visible: control.checked
anchors.centerIn: parent
}
}
}
@@ -36,7 +36,6 @@ Column {
StatusBaseText {
id: title
width: parent.width
verticalAlignment: Text.AlignVCenter
font.pixelSize: 13
color: Theme.palette.baseColor1
@@ -47,9 +46,7 @@ Column {
columns: 6
rowSpacing: 16
columnSpacing: 32
Repeater {
objectName: "statusColorRepeater"
model: root.model
delegate: StatusColorRadioButton {
implicitWidth: root.diameter
+1 -10
View File
@@ -24,8 +24,6 @@ Item {
property alias label: labelItem.text
property alias validationError: validationErrorItem.text
property string popupContentItemObjectName: ""
implicitWidth: layout.implicitWidth
implicitHeight: layout.implicitHeight
@@ -76,13 +74,6 @@ Item {
: comboBox.hovered
? Theme.palette.primaryColor2
: "transparent"
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.NoButton
enabled: root.enabled
}
}
contentItem: StatusBaseText {
@@ -132,7 +123,7 @@ Item {
contentItem: StatusListView {
id: listView
objectName: root.popupContentItemObjectName
implicitWidth: contentWidth
implicitHeight: contentHeight
+9 -5
View File
@@ -3,15 +3,19 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
StatusBaseButton {
id: statusFlatButton
normalColor: "transparent"
hoverColor: type === StatusBaseButton.Type.Normal ? Theme.palette.primaryColor3
: Theme.palette.dangerColor3
disabledColor: "transparent"
hoverColor: type === StatusBaseButton.Type.Normal ? Theme.palette.primaryColor3
: Theme.palette.dangerColor3
disaledColor: "transparent"
textColor: type === StatusBaseButton.Type.Normal ? Theme.palette.primaryColor1
: Theme.palette.dangerColor1
disabledTextColor: Theme.palette.baseColor1
borderColor: (type === StatusBaseButton.Type.Normal || hovered) && !loading ? "transparent"
: Theme.palette.baseColor2
border.color: type === StatusBaseButton.Type.Normal || hovered ? "transparent"
: Theme.palette.baseColor2
rightPadding: icon.name !== "" ? 18 : defaultRightPadding
leftPadding: icon.name !== "" ? 14 : defaultLeftPadding
}
@@ -7,7 +7,7 @@ import StatusQ.Components 0.1
Rectangle {
id: statusFlatRoundButton
property StatusAssetSettings icon: StatusAssetSettings {
property StatusIconSettings icon: StatusIconSettings {
width: 23
height: 23
rotation: 0
@@ -113,11 +113,12 @@ Row {
implicitHeight: 32
topPadding: 8
bottomPadding: 0
horizontalPadding: 4
defaultLeftPadding: 4
defaultRightPadding: 4
hoverColor: Theme.palette.statusFloatingButtonHighlight
normalColor: Theme.palette.baseColor3
asset.name: "more"
asset.bgColor: "transparent"
icon.name: "more"
icon.background.color: "transparent"
onClicked: popupMenu.popup(parent.x, y + height + 8)
}
}
+8 -7
View File
@@ -26,13 +26,14 @@ TabButton {
id: identicon
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
asset.isImage: (statusIconTabButton.icon.source.toString() !== "")
asset.name: asset.isImage ?
statusIconTabButton.icon.source : statusIconTabButton.icon.name
asset.width: asset.isImage ? 28 : statusIconTabButton.icon.width
asset.height: asset.isImage ? 28 : statusIconTabButton.icon.height
asset.color: (statusIconTabButton.hovered || highlighted || statusIconTabButton.checked) ? Theme.palette.primaryColor1 : statusIconTabButton.icon.color
asset.isLetterIdenticon: statusIconTabButton.name !== "" && !asset.isImage
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()
name: statusIconTabButton.name
}
}
@@ -64,7 +64,6 @@ AbstractButton {
width: root.icon.width
height: root.icon.height
rotation: root.iconRotation
visible: status == Image.Ready
}
StatusBaseText {
Layout.alignment: Qt.AlignVCenter
+2 -7
View File
@@ -48,7 +48,6 @@ Item {
This property holds a reference to the TextEdit's valid property.
*/
property alias valid: statusBaseInput.valid
/*!
\qmlproperty alias StatusInput::pending
This property holds a reference to the TextEdit's pending property.
@@ -244,7 +243,7 @@ Item {
This function resets the text input validation and text.
*/
function reset() {
statusBaseInput.valid = false
statusBaseInput.valid = true
statusBaseInput.pristine = true
statusBaseInput.text = ""
root.errorMessage = ""
@@ -277,12 +276,8 @@ Item {
valid: result
}
}
errors[validator.name] = result
// the only way to trigger bindings for var property
errors = errors
result.errorMessage = validator.errorMessage
errors[validator.name] = result
statusBaseInput.valid = statusBaseInput.valid && false
}
}
+4 -10
View File
@@ -15,10 +15,11 @@ ItemDelegate {
icon.width: 16
icon.height: 16
contentItem: RowLayout {
contentItem: RowLayout {
spacing: root.spacing
StatusIcon {
id: iconItem
Layout.alignment: Qt.AlignVCenter
visible: !!icon
icon: root.icon.name
@@ -42,14 +43,7 @@ ItemDelegate {
background: Rectangle {
color: root.highlighted
? Theme.palette.statusPopupMenu.hoverBackgroundColor
: "transparent"
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.NoButton
enabled: root.enabled
}
? Theme.palette.statusPopupMenu.hoverBackgroundColor
: "transparent"
}
}
+9 -25
View File
@@ -39,10 +39,10 @@ Rectangle {
id: root
/*!
\qmlproperty string StatusItemPicker::asset
This property holds the asset(image/icon) settings information.
\qmlproperty string StatusItemPicker::image
This property holds the image settings information.
*/
property StatusAssetSettings asset
property StatusImageSettings image
/*!
\qmlproperty string StatusItemPicker::name
@@ -50,12 +50,6 @@ Rectangle {
*/
property string name
/*!
\qmlproperty int StatusItemPicker::namePixelSize
This property holds pixel size of the name to be displayed.
*/
property int namePixelSize: 15
/*!
\qmlproperty string StatusItemPicker::shortName
This property holds the secondary text or short name to be displayed.
@@ -87,15 +81,6 @@ Rectangle {
*/
property ButtonGroup radioGroup
/*!
\qmlproperty int StatusItemPicker::radioButtonSize
This property holds size type of the radio button.
Possible values are:
- Small
- Large (default size)
*/
property int radioButtonSize: StatusRadioButton.Size.Large
/*!
\qmlsignal StatusItemPicker::checkedChanged(bool checked)
This signal is emitted when the item is selected by pressing the radiobutton or the checkbox.
@@ -110,7 +95,7 @@ Rectangle {
QtObject {
id: d
readonly property int minShortNameWidth: root.shortName ? 50 : 0
property int minShortNameWidth: 50
function availableTextWidth() {
return root.width - imageItem.width - row.spacing - shortNameItem.anchors.rightMargin - selector.width - selector.anchors.rightMargin - 24/*Margin between both texts*/
@@ -127,10 +112,10 @@ Rectangle {
StatusIcon {
id: imageItem
anchors.verticalCenter: parent.verticalCenter
source: root.asset && root.asset.name ? root.asset.name : ""
width: root.asset ? root.asset.width : 0
height: root.asset ? root.asset.height : 0
visible: root.asset && root.asset.name !== undefined
source: root.image.source ? root.image.source : ""
width: root.image.width
height: root.image.height
visible: root.image.source !== undefined
}
StatusBaseText {
@@ -141,7 +126,7 @@ Rectangle {
dummyNameItem.width
text: root.name
color: Theme.palette.directColor1
font.pixelSize: root.namePixelSize
font.pixelSize: 15
clip: true
elide: Text.ElideRight
}
@@ -182,7 +167,6 @@ Rectangle {
Component {
id: radioBtn
StatusRadioButton {
size: root.radioButtonSize
ButtonGroup.group: root.radioGroup
checked: root.selected
onCheckedChanged: {
@@ -1,108 +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
import StatusQ.Controls 0.1
/*!
\qmltype StatusPasswordInput
\inherits Item
\inqmlmodule StatusQ.Controls
\since StatusQ.Controls 0.1
\brief The StatusPasswordInput control provides a generic user password input with an option to display signing phrase
Example of how to use it:
\qml
StatusPasswordInput {
signingPhrase: "orange hello cygnet"
placeholderText: qsTr("Password")
}
\endqml
For a list of available components see StatusQ.
*/
TextField {
id: root
/*!
\qmlproperty string StatusPasswordInput::signingPhrase
This property sets the signingPhrase of TextField field and signing seed phrase.
*/
property string signingPhrase: ""
QtObject {
id: d
readonly property int inputTextPadding: 16
readonly property int pixelSize: 15
readonly property int radius: 8
readonly property int signingPhrasePadding: 8
readonly property int signingPhraseWordPadding: 8
readonly property int signingPhraseWordsSpacing: 8
readonly property int signingPhraseWordsHeight: 30
}
leftPadding: d.inputTextPadding
rightPadding: root.signingPhrase !== ""?
phrase.width + phrase.anchors.leftMargin + phrase.anchors.rightMargin :
d.inputTextPadding
verticalAlignment: Text.AlignVCenter
implicitWidth: 480
implicitHeight: 44
placeholderTextColor: Theme.palette.baseColor1
echoMode: TextInput.Password
font.pixelSize: d.pixelSize
font.family: Theme.palette.baseFont.name
color: Theme.palette.directColor1
selectionColor: Theme.palette.primaryColor2
selectedTextColor: Theme.palette.directColor1
background: Rectangle {
id: inputRectangle
anchors.fill: parent
color: Theme.palette.baseColor5
radius: d.radius
border.width: root.focus ? 1 : 0
border.color: {
if (root.focus) {
return Theme.palette.primaryColor1
}
return "transparent"
}
}
RowLayout {
id: phrase
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: d.signingPhrasePadding
anchors.rightMargin: d.signingPhrasePadding
spacing: d.signingPhraseWordsSpacing
visible: root.signingPhrase !== ""
Repeater {
model: root.signingPhrase.split(" ")
delegate: Rectangle {
width: signingPhraseWord.implicitWidth + 2 * d.signingPhraseWordPadding
height: d.signingPhraseWordsHeight
color: Theme.palette.indirectColor1
radius: d.radius
StatusBaseText {
id: signingPhraseWord
anchors.centerIn: parent
color: Theme.palette.primaryColor1
font.pixelSize: root.font.pixelSize
font.family: root.font.family
text: modelData
}
}
}
}
}
+7 -7
View File
@@ -14,13 +14,13 @@ Button {
property var type: StatusPickerButton.Type.Next
/*!
\qmlproperty StatusAssetSettings StatusPickerButton::image
\qmlproperty StatusImageSettings StatusPickerButton::image
This property holds the image settings information.
*/
property StatusAssetSettings asset: StatusAssetSettings {
property StatusImageSettings image: StatusImageSettings {
width: 20
height: 20
imgIsIdenticon: false
isIdenticon: false
}
enum Type {
@@ -51,11 +51,11 @@ Button {
height: root.icon.height
}
StatusRoundedImage {
visible: root.asset.name.toString() !== ""
visible: root.image.source.toString() !== ""
Layout.alignment: Qt.AlignVCenter
Layout.preferredWidth: root.asset.width
Layout.preferredHeight: root.asset.height
image.source: root.asset.name
Layout.preferredWidth: root.image.width
Layout.preferredHeight: root.image.height
image.source: root.image.source
}
StatusBaseText {
Layout.fillWidth: true
+45 -69
View File
@@ -77,20 +77,6 @@ Item {
*/
property int circleDiameter: 16
/*!
\qmlproperty int StatusPinInput::additionalSpacingOnEveryNItems
This property allows you to customize spacing among every N-th pin. By default the value is 0, which
means only regular `circleSpacing` will be applied, meaning that spacing among all pins will be the same.
*/
property int additionalSpacingOnEveryNItems: 0
/*!
\qmlproperty int StatusPinInput::additionalSpacing
This property allows you to customize spacing between pin circles on every `additionalSpacingOnEveryNItems` items.
This additionalSpacing won't be applied if `additionalSpacingOnEveryNItems` is set to `0`.
*/
property int additionalSpacing: 0
QtObject {
id: d
property int currentPinIndex: 0
@@ -165,8 +151,8 @@ Item {
}
}
implicitWidth: childrenRect.width
implicitHeight: childrenRect.height
width: (root.circleDiameter + root.circleSpacing) * root.pinLen - root.circleSpacing
height: root.circleDiameter
// Pin input data management object:
TextInput {
@@ -210,66 +196,56 @@ Item {
id: repeater
model: root.pinLen
Item {
id: container
Rectangle {
id: background
property string innerState: "EMPTY"
property alias blinkingAnimation: blinkingAnimation
property alias innerOpacity: inner.opacity
height: root.circleDiameter
width: {
if (index > 0 && index < root.pinLen-1 && (index+1) % root.additionalSpacingOnEveryNItems == 0) {
return root.circleDiameter + root.additionalSpacing
}
return root.circleDiameter
}
width: root.circleDiameter
height: width
color: Theme.palette.primaryColor2
radius: 0.5 * width
Rectangle {
width: root.circleDiameter
height: width
color: Theme.palette.primaryColor2
radius: 0.5 * width
Rectangle {
id: inner
state: background.innerState
anchors.centerIn: parent
height: width
color: Theme.palette.primaryColor1
radius: 0.5 * width
states: [
State {
name: "NEXT"
StateChangeScript { script: { if(inputText.focus) blinkingAnimation.start() } }
PropertyChanges {target: inner; width: root.circleDiameter / 2}
},
State {
name: "FILLED"
StateChangeScript { script: if(blinkingAnimation.running) blinkingAnimation.stop() }
PropertyChanges {target: inner; width: root.circleDiameter}
PropertyChanges {target: inner; opacity: 1}
},
State {
name: "EMPTY"
StateChangeScript { script: if(blinkingAnimation.running) blinkingAnimation.stop() }
PropertyChanges {target: inner; width: 0}
PropertyChanges {target: inner; opacity: 1}
}
]
Rectangle {
id: inner
state: container.innerState
anchors.centerIn: parent
height: width
color: Theme.palette.primaryColor1
radius: 0.5 * width
states: [
State {
name: "NEXT"
StateChangeScript { script: { if(inputText.focus) blinkingAnimation.start() } }
PropertyChanges {target: inner; width: root.circleDiameter / 2}
},
State {
name: "FILLED"
StateChangeScript { script: if(blinkingAnimation.running) blinkingAnimation.stop() }
PropertyChanges {target: inner; width: root.circleDiameter}
PropertyChanges {target: inner; opacity: 1}
},
State {
name: "EMPTY"
StateChangeScript { script: if(blinkingAnimation.running) blinkingAnimation.stop() }
PropertyChanges {target: inner; width: 0}
PropertyChanges {target: inner; opacity: 1}
}
]
// Animation on transitions
Behavior on width { NumberAnimation { duration: 200 } }
// Animation on transitions
Behavior on width { NumberAnimation { duration: 200 } }
// Animation on "cursor" blinking
SequentialAnimation {
id: blinkingAnimation
loops: Animation.Infinite
running: visible
NumberAnimation { target: inner; property: "opacity"; to: 0; duration: 800;}
NumberAnimation { target: inner; property: "opacity"; to: 1; duration: 800;}
}
}
}
// Animation on "cursor" blinking
SequentialAnimation {
id: blinkingAnimation
loops: Animation.Infinite
running: visible
NumberAnimation { target: inner; property: "opacity"; to: 0; duration: 800;}
NumberAnimation { target: inner; property: "opacity"; to: 1; duration: 800;}
}
}
}
}
}
+21 -30
View File
@@ -1,50 +1,41 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQml 2.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
RadioButton {
id: root
id: statusRadioButton
/*!
\qmlproperty int StatusRadioButton::size
This property holds size type of the radio button.
Possible values are:
- Small
- Large (default size)
*/
property int size: StatusRadioButton.Size.Large
enum Size {
Small,
Large
}
width: indicator.implicitWidth
indicator: Rectangle {
implicitWidth: root.size === StatusRadioButton.Size.Large ? 20 : 14
implicitHeight: root.size === StatusRadioButton.Size.Large ? 20 : 14
x: root.text ? (root.mirrored ? root.width - width - root.rightPadding : root.leftPadding) : root.leftPadding + (root.availableWidth - width) / 2
y: root.topPadding + (root.availableHeight - height) / 2
radius: width / 2
color: root.checked ? Theme.palette.primaryColor1 : Theme.palette.directColor8
implicitWidth: 20
implicitHeight: 20
x: 0
y: 6
radius: 10
color: statusRadioButton.checked ? Theme.palette.primaryColor1
: Theme.palette.directColor8
Rectangle {
width: root.size === StatusRadioButton.Size.Large ? 12 : 8
height: root.size === StatusRadioButton.Size.Large ? 12 : 8
radius: width / 2
anchors.centerIn: parent
color: Theme.palette.white
visible: root.checked
width: 12
height: 12
radius: 6
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: statusRadioButton.checked ? Theme.palette.white : "transparent"
visible: statusRadioButton.checked
}
}
contentItem: StatusBaseText {
font: root.font
text: root.text
text: statusRadioButton.text
color: Theme.palette.directColor1
verticalAlignment: Text.AlignVCenter
leftPadding: root.indicator && !root.mirrored ? root.indicator.width + root.spacing : 0
rightPadding: root.indicator && root.mirrored ? root.indicator.width + root.spacing : 0
leftPadding: !!statusRadioButton.text ? statusRadioButton.indicator.width + statusRadioButton.spacing
: statusRadioButton.indicator.width
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ import StatusQ.Components 0.1
Rectangle {
id: statusRoundButton
property StatusAssetSettings icon: StatusAssetSettings {
property StatusIconSettings icon: StatusIconSettings {
width: 23
height: 23
rotation: 0
+1 -1
View File
@@ -47,7 +47,7 @@ T.ScrollBar {
contentItem: Rectangle {
color: Theme.palette.primaryColor2
opacity: enabled && (root.hovered || root.active || (root.policy === T.ScrollBar.AlwaysOn)) ? 1.0 : 0.0
opacity: enabled && (root.hovered || root.active) ? 1.0 : 0.0
radius: Math.min(width, height) / 2
Behavior on opacity { NumberAnimation { duration: 100 } }
+2 -3
View File
@@ -23,7 +23,6 @@ Item {
property var model
property alias selectMenu: selectMenu
property color bgColorHover: bgColor
// TODO: Fix the indirect handling of children
property alias selectedItemComponent: selectedItemContainer.children
property bool caretVisible: true
property int caretRightMargin: 16
@@ -55,7 +54,7 @@ Item {
Rectangle {
property bool hovered: false
id: inputRectangle
height: selectedItemContainer.implicitHeight
height: 56
color: hovered ? bgColorHover : bgColor
radius: 8
anchors.top: root.hasLabel ? inputLabel.bottom : parent.top
@@ -65,7 +64,7 @@ Item {
border.width: !!validationError ? 1 : 0
border.color: Theme.palette.dangerColor1
GridLayout {
Item {
id: selectedItemContainer
anchors.fill: parent
}
+13 -3
View File
@@ -5,7 +5,6 @@ import QtQuick.Controls 2.14 as QC
import StatusQ.Controls 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
Item {
@@ -58,7 +57,18 @@ Item {
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
@@ -73,7 +83,7 @@ Item {
font.family: Theme.palette.baseFont.name
color: Theme.palette.directColor1
textFormat: Text.RichText
onCursorRectangleChanged: Utils.ensureVisible(flick, cursorRectangle)
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
wrapMode: statusSelectableText.multiline ? Text.WrapAtWordBoundaryOrAnywhere : TextEdit.NoWrap
Keys.forwardTo: [statusSelectableText]
@@ -6,7 +6,7 @@ import StatusQ.Core.Theme 0.1
Item {
id: root
property StatusAssetSettings icon: StatusAssetSettings {
property StatusIconSettings icon: StatusIconSettings {
width: 24
height: 24
name: ""
+2 -6
View File
@@ -25,21 +25,17 @@ import StatusQ.Components 0.1
TabButton {
id: root
readonly property alias badge: statusBadge
property alias badge: statusBadge
leftPadding: 12
rightPadding: 12
background: Item { }
contentItem: MouseArea {
contentItem: Item {
implicitWidth: contentItemGrid.implicitWidth
implicitHeight: contentItemGrid.implicitHeight + 15
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.NoButton
enabled: root.enabled
RowLayout {
id: contentItemGrid
+2 -1
View File
@@ -18,7 +18,7 @@ ToolTip {
property int offset: 0
property alias arrow: arrow
implicitWidth: Math.min(maxWidth, contentItem.implicitWidth + 16)
implicitWidth: Math.min(maxWidth, textContent.implicitWidth + 16)
leftPadding: 8
rightPadding: 8
topPadding: 8
@@ -65,6 +65,7 @@ ToolTip {
}
}
contentItem: StatusBaseText {
id: textContent
text: statusToolTip.text
color: Theme.palette.white
wrapMode: Text.WordWrap
-1
View File
@@ -51,4 +51,3 @@ StatusComboBox 0.1 StatusComboBox.qml
StatusItemDelegate 0.1 StatusItemDelegate.qml
StatusTextArea 0.1 StatusTextArea.qml
StatusBackButton 0.1 StatusBackButton.qml
StatusPasswordInput 0.1 StatusPasswordInput.qml
@@ -0,0 +1,10 @@
import QtQuick 2.13
QtObject {
id: statusIconBackgroundSettings
property color color: "transparent"
property real width
property real height
property int radius
}

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