Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bdc330c3f |
|
Before Width: | Height: | Size: 21 KiB |
@@ -25,11 +25,10 @@ Rectangle {
|
||||
id: appSectionType
|
||||
readonly property int chat: 0
|
||||
readonly property int community: 1
|
||||
readonly property int communitiesPortal: 2
|
||||
readonly property int wallet: 3
|
||||
readonly property int wallet: 2
|
||||
readonly property int browser: 3
|
||||
readonly property int nodeManagement: 5
|
||||
readonly property int profileSettings: 6
|
||||
readonly property int nodeManagement: 4
|
||||
readonly property int profileSettings: 5
|
||||
readonly property int apiDocumentation: 100
|
||||
readonly property int demoApp: 101
|
||||
}
|
||||
@@ -119,11 +118,6 @@ Rectangle {
|
||||
appView.sourceComponent = statusAppChatView
|
||||
demoApp.setActiveItem(model.sectionId)
|
||||
}
|
||||
else if(model.sectionType === appSectionType.communitiesPortal)
|
||||
{
|
||||
appView.sourceComponent = statusCommunityPortalView
|
||||
demoApp.setActiveItem(model.sectionId)
|
||||
}
|
||||
else if(model.sectionType === appSectionType.profileSettings)
|
||||
{
|
||||
appView.sourceComponent = statusAppProfileSettingsView
|
||||
@@ -211,11 +205,6 @@ Rectangle {
|
||||
StatusAppProfileSettingsView { }
|
||||
}
|
||||
|
||||
Component {
|
||||
id: statusCommunityPortalView
|
||||
StatusAppCommunitiesPortalView { }
|
||||
}
|
||||
|
||||
DemoContactRequestsModal {
|
||||
id: demoContactRequestsModal
|
||||
anchors.centerIn: parent
|
||||
|
||||
@@ -3,10 +3,9 @@ import QtQuick.Layouts 1.14
|
||||
import QtQuick.Dialogs 1.3
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
|
||||
Column {
|
||||
spacing: 10
|
||||
Grid {
|
||||
@@ -174,25 +173,6 @@ Column {
|
||||
loading: true
|
||||
}
|
||||
|
||||
// transparent
|
||||
|
||||
StatusRoundButton {
|
||||
type: StatusRoundButton.Type.Tertiary
|
||||
icon.name: "info"
|
||||
}
|
||||
|
||||
StatusRoundButton {
|
||||
type: StatusRoundButton.Type.Tertiary
|
||||
icon.name: "info"
|
||||
enabled: false
|
||||
}
|
||||
|
||||
StatusRoundButton {
|
||||
type: StatusRoundButton.Type.Tertiary
|
||||
icon.name: "info"
|
||||
loading: true
|
||||
}
|
||||
|
||||
// Rounded blue
|
||||
|
||||
StatusFlatRoundButton {
|
||||
@@ -327,20 +307,12 @@ Column {
|
||||
onClicked: {
|
||||
colorDialog.open();
|
||||
}
|
||||
}
|
||||
|
||||
StatusColorDialog {
|
||||
id: colorDialog
|
||||
anchors.centerIn: parent
|
||||
property bool colorSelected: false
|
||||
onAccepted: {
|
||||
colorSelected = true;
|
||||
ColorDialog {
|
||||
id: colorDialog
|
||||
property bool colorSelected: false
|
||||
onAccepted: {
|
||||
colorSelected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Button with emoji
|
||||
StatusButton {
|
||||
text: "Button with Emoji"
|
||||
icon.emoji: "🖼️️"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,16 +189,6 @@ GridLayout {
|
||||
value: 40
|
||||
}
|
||||
|
||||
StatusLabeledSlider {
|
||||
width: 360
|
||||
model: [ qsTr("XS"), qsTr("S"), qsTr("M"), qsTr("L"), qsTr("XL"), qsTr("XXL")]
|
||||
}
|
||||
|
||||
StatusLabeledSlider {
|
||||
width: 360
|
||||
model: [ qsTr("50%"), qsTr("100%"), qsTr("150%"), qsTr("200%")]
|
||||
}
|
||||
|
||||
StatusBanner {
|
||||
id: banner
|
||||
width: 360
|
||||
@@ -208,7 +198,7 @@ GridLayout {
|
||||
}
|
||||
|
||||
StatusProgressBar {
|
||||
id: progressBar
|
||||
id: progressBar
|
||||
text: "Weak"
|
||||
value: 0.5
|
||||
fillColor : Theme.palette.pinColor1
|
||||
|
||||
@@ -10,96 +10,31 @@ import StatusQ.Layout 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
Column {
|
||||
spacing: 10
|
||||
spacing: 5
|
||||
|
||||
StatusChatToolBar {
|
||||
toolbarComponent: chatInfoButton1
|
||||
width: 518
|
||||
|
||||
Component {
|
||||
id: chatInfoButton1
|
||||
|
||||
StatusChatInfoButton {
|
||||
width: Math.min(implicitWidth, parent.width)
|
||||
title: "Some contact"
|
||||
subTitle: "Contact"
|
||||
icon.color: Theme.palette.miscColor7
|
||||
type: StatusChatInfoButton.Type.OneToOneChat
|
||||
}
|
||||
}
|
||||
chatInfoButton.title: "Some contact"
|
||||
chatInfoButton.subTitle: "Contact"
|
||||
chatInfoButton.icon.color: Theme.palette.miscColor7
|
||||
chatInfoButton.type: StatusChatInfoButton.Type.OneToOneChat
|
||||
}
|
||||
|
||||
StatusChatToolBar {
|
||||
toolbarComponent: chatInfoButton2
|
||||
width: 518
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
chatInfoButton.title: "Some contact"
|
||||
chatInfoButton.subTitle: "Contact"
|
||||
chatInfoButton.icon.color: Theme.palette.miscColor7
|
||||
chatInfoButton.type: StatusChatInfoButton.Type.PublicChat
|
||||
chatInfoButton.pinnedMessagesCount: 1
|
||||
chatInfoButton.muted: true
|
||||
}
|
||||
|
||||
|
||||
StatusChatToolBar {
|
||||
chatInfoButton.title: "Some contact"
|
||||
chatInfoButton.subTitle: "Contact"
|
||||
chatInfoButton.icon.color: Theme.palette.miscColor7
|
||||
chatInfoButton.type: StatusChatInfoButton.Type.OneToOneChat
|
||||
chatInfoButton.pinnedMessagesCount: 1
|
||||
notificationCount: 1
|
||||
toolbarComponent: chatInfoButton3
|
||||
width: 518
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusChatToolBar {
|
||||
notificationCount: 1
|
||||
toolbarComponent: tagSelector
|
||||
width: 518
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
|
||||
@@ -394,13 +394,13 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
StatusMemberListItem {
|
||||
nickName: "This is an example"
|
||||
userName: "annabelle"
|
||||
pubKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
isVerified: true
|
||||
isContact: true
|
||||
chatKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
|
||||
isMutualContact: true
|
||||
image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
|
||||
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||
image.isIdenticon: true
|
||||
status: 1 // FIXME: use enum
|
||||
isOnline: true
|
||||
ringSettings.ringSpecModel:
|
||||
ListModel {
|
||||
ListElement {colorId: 13; segmentLength: 5}
|
||||
@@ -416,62 +416,29 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
|
||||
StatusMemberListItem {
|
||||
nickName: "carmen.eth"
|
||||
isUntrustworthy: true
|
||||
isOnline: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
}
|
||||
|
||||
StatusMemberListItem {
|
||||
nickName: "very-long-annoying-nickname.eth"
|
||||
isUntrustworthy: true
|
||||
isOnline: false
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
}
|
||||
|
||||
StatusMemberListItem {
|
||||
nickName: "This girl I know from work"
|
||||
userName: "annabelle"
|
||||
status: 1 // FIXME: use enum
|
||||
isOnline: true
|
||||
}
|
||||
|
||||
StatusMemberListItem {
|
||||
nickName: "Mark Cuban"
|
||||
userName: "annabelle"
|
||||
pubKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
isContact: true
|
||||
chatKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
isMutualContact: true
|
||||
image.source: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
|
||||
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||
image.isIdenticon: true
|
||||
}
|
||||
|
||||
StatusMemberListItem {
|
||||
nickName: "admin.guy"
|
||||
isAdmin: true
|
||||
isUntrustworthy: true
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
text: "Loading features:"
|
||||
font.pixelSize: 17
|
||||
}
|
||||
|
||||
StatusListItem {
|
||||
title: "Nokia 3310"
|
||||
subTitle: "Incoming device"
|
||||
label: "loading: true"
|
||||
icon.emoji: "😁"
|
||||
icon.color: "hotpink"
|
||||
icon.letterSize: 14
|
||||
icon.isLetterIdenticon: true
|
||||
loading: true
|
||||
}
|
||||
|
||||
StatusListItem {
|
||||
title: "Nokia 3310"
|
||||
subTitle: "Device"
|
||||
label: "loadingFailed: true"
|
||||
icon.emoji: "😁"
|
||||
icon.color: "hotpink"
|
||||
icon.letterSize: 14
|
||||
icon.isLetterIdenticon: true
|
||||
loadingFailed: true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,6 @@ import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
|
||||
Column {
|
||||
spacing: 20
|
||||
@@ -86,12 +83,6 @@ Column {
|
||||
onClicked: advancedHeaderFooterModal.open()
|
||||
}
|
||||
|
||||
|
||||
StatusButton {
|
||||
text: "Modal with Floating header Buttons"
|
||||
onClicked: floatingHeaderModal.open()
|
||||
}
|
||||
|
||||
StatusModal {
|
||||
id: simpleModal
|
||||
anchors.centerIn: parent
|
||||
@@ -403,57 +394,10 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
}
|
||||
}
|
||||
|
||||
StatusModal {
|
||||
id: floatingHeaderModal
|
||||
anchors.centerIn: parent
|
||||
height: 200
|
||||
showHeader: false
|
||||
showFooter: false
|
||||
showAdvancedHeader: true
|
||||
hasFloatingButtons: true
|
||||
advancedHeaderComponent: StatusFloatingButtonsSelector {
|
||||
id: floatingHeader
|
||||
model: dummyAccountsModel
|
||||
delegate: Rectangle {
|
||||
width: button.width
|
||||
height: button.height
|
||||
radius: 8
|
||||
visible: visibleIndices.includes(index)
|
||||
StatusButton {
|
||||
id: button
|
||||
topPadding: 8
|
||||
bottomPadding: 0
|
||||
implicitHeight: 32
|
||||
defaultLeftPadding: 4
|
||||
text: name
|
||||
icon.emoji: !!emoji ? emoji: ""
|
||||
icon.emojiSize: Emoji.size.middle
|
||||
icon.name: !emoji ? "filled-account": ""
|
||||
normalColor: "transparent"
|
||||
highlighted: index === floatingHeader.currentIndex
|
||||
onClicked: {
|
||||
floatingHeader.currentIndex = index
|
||||
}
|
||||
}
|
||||
}
|
||||
popupMenuDelegate: StatusListItem {
|
||||
implicitWidth: 272
|
||||
title: name
|
||||
onClicked: floatingHeader.itemSelected(index)
|
||||
visible: !visibleIndices.includes(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: dummyAccountsModel
|
||||
ListElement{name: "Account 1"; iconName: "filled-account"; emoji: "🥑"}
|
||||
ListElement{name: "Account 1"; iconName: "filled-account"}
|
||||
ListElement{name: "Account 2"; iconName: "filled-account"}
|
||||
ListElement{name: "Account 3"; iconName: "filled-account"}
|
||||
ListElement{name: "Account 4"; iconName: "filled-account"}
|
||||
ListElement{name: "Account 5"; iconName: "filled-account"}
|
||||
ListElement{name: "Account 6"; iconName: "filled-account"}
|
||||
ListElement{name: "Account 7"; iconName: "filled-account"}
|
||||
}
|
||||
|
||||
StatusSpellcheckingMenuItems {
|
||||
|
||||
@@ -36,7 +36,7 @@ Page {
|
||||
var index = -1;
|
||||
if (!!contactsModel) {
|
||||
for (var i = 0; i < contactsModel.count; i++) {
|
||||
if (contactsModel.get(i).pubKey === pubKey) {
|
||||
if (contactsModel.get(i).publicId === pubKey) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
@@ -58,11 +58,6 @@ Page {
|
||||
}
|
||||
return randomString.join().toString().replace(/,/g, '');
|
||||
}
|
||||
colorIdForPubkeyGetter: function (pubKey) {
|
||||
//for simulation purposes only, in real app
|
||||
//this would be Utils.colorIdForPubkey(pubKey);
|
||||
return Math.floor(Math.random() * 10);
|
||||
}
|
||||
onTextChanged: {
|
||||
sortModel(root.contactsModel);
|
||||
}
|
||||
|
||||
@@ -145,8 +145,15 @@ StatusAppThreePanelLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
StatusChatToolBar {
|
||||
anchors.top: parent.top
|
||||
width: parent.width
|
||||
toolbarComponent: statusChatInfoButton
|
||||
|
||||
chatInfoButton.title: "Amazing Funny Squirrel"
|
||||
chatInfoButton.subTitle: "Contact"
|
||||
chatInfoButton.icon.color: Theme.palette.miscColor7
|
||||
chatInfoButton.type: StatusChatInfoButton.Type.OneToOneChat
|
||||
chatInfoButton.pinnedMessagesCount: 1
|
||||
|
||||
searchButton.visible: false
|
||||
membersButton.visible: false
|
||||
notificationCount: 1
|
||||
@@ -179,19 +186,6 @@ StatusAppThreePanelLayout {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Layouts 1.13
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
import "../demoapp/data" 1.0
|
||||
|
||||
|
||||
ScrollView {
|
||||
id: root
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property ListModel featuredCommunitiesModel: Models.featuredCommunitiesModel
|
||||
property ListModel popularCommunitiesModel: Models.curatedCommunitiesModel
|
||||
property ListModel tagsModel: Models.tagsModel
|
||||
|
||||
property string searchText: ""
|
||||
property int layoutVMargin: 70
|
||||
property int layoutHMargin: 64
|
||||
property int titlePixelSize: 28
|
||||
property int subtitlePixelSize: 17
|
||||
property int stylePadding: 16
|
||||
|
||||
function navigateToCommunity(communityId) {
|
||||
console.info("Clicked community ID: " + communityId)
|
||||
}
|
||||
}
|
||||
|
||||
contentHeight: column.height + d.layoutVMargin
|
||||
contentWidth: column.width + d.layoutHMargin
|
||||
clip: true
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
Layout.leftMargin: d.layoutHMargin
|
||||
Layout.topMargin: 20
|
||||
text: qsTr("Featured")
|
||||
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
|
||||
|
||||
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("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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,10 +166,13 @@ StatusAppThreePanelLayout {
|
||||
centerPanel: Item {
|
||||
StatusChatToolBar {
|
||||
id: statusChatToolBar
|
||||
|
||||
anchors.top: parent.top
|
||||
width: parent.width
|
||||
toolbarComponent: statusChatInfoButton
|
||||
|
||||
chatInfoButton.title: "general"
|
||||
chatInfoButton.subTitle: "Community Chat"
|
||||
chatInfoButton.icon.color: Theme.palette.miscColor6
|
||||
chatInfoButton.type: StatusChatInfoButton.Type.CommunityChat
|
||||
onSearchButtonClicked: {
|
||||
searchButton.highlighted = !searchButton.highlighted;
|
||||
searchPopup.setSearchSelection(communityDetailModalTitle,
|
||||
@@ -181,18 +184,6 @@ StatusAppThreePanelLayout {
|
||||
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 {
|
||||
@@ -267,15 +258,15 @@ StatusAppThreePanelLayout {
|
||||
model: Models.membersListModel
|
||||
delegate: StatusMemberListItem {
|
||||
implicitWidth: parent.width
|
||||
nickName: model.localNickname
|
||||
userName: model.displayName
|
||||
pubKey: model.pubKey
|
||||
isVerified: model.isVerified
|
||||
isUntrustworthy: model.isUntrustworthy
|
||||
isContact: model.isContact
|
||||
nickName: model.nickName
|
||||
userName: model.name
|
||||
chatKey: model.publicId
|
||||
trustIndicator: model.trustIndicator
|
||||
isMutualContact: model.isMutualContact
|
||||
image.source: model.icon
|
||||
image.isIdenticon: false
|
||||
status: model.onlineStatus
|
||||
image.isIdenticon: model.isIdenticon
|
||||
isOnline: model.onlineStatus
|
||||
ringSettings.ringSpecModel: model.ringSpecModel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -843,50 +843,69 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
property var membersListModel: ListModel {
|
||||
id: membersList
|
||||
ListElement {
|
||||
localNickname: "This is an example"
|
||||
displayName: "Maria"
|
||||
pubKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
isVerified: true
|
||||
isUntrustworthy: false
|
||||
isContact: true
|
||||
onlineStatus: 1
|
||||
nickName: "This is an example"
|
||||
name: "Maria"
|
||||
publicId: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Verified
|
||||
isMutualContact: true
|
||||
onlineStatus: true
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
|
||||
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||
isAdmin: false
|
||||
isIdenticon: true
|
||||
ringSpecModel: [ ListElement {colorId: 13; segmentLength: 5},
|
||||
ListElement {colorId: 31; segmentLength: 5},
|
||||
ListElement {colorId: 10; segmentLength: 1},
|
||||
ListElement {colorId: 2; segmentLength: 5},
|
||||
ListElement {colorId: 26; segmentLength: 2},
|
||||
ListElement {colorId: 19; segmentLength: 4},
|
||||
ListElement {colorId: 28; segmentLength: 3} ]
|
||||
}
|
||||
ListElement {
|
||||
localNickname: ""
|
||||
displayName: "carmen.eth"
|
||||
pubKey: "0x043a7ed78362567894688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
isVerified: false
|
||||
isUntrustworthy: true
|
||||
isContact: false
|
||||
onlineStatus: 0
|
||||
nickName: ""
|
||||
name: "carmen.eth"
|
||||
publicId: "0x043a7ed78362567894688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
isMutualContact: false
|
||||
onlineStatus: false
|
||||
icon: ""
|
||||
isAdmin: false
|
||||
isIdenticon: false
|
||||
}
|
||||
ListElement {
|
||||
localNickname: "This girl I know from work"
|
||||
displayName: "annabelle"
|
||||
pubKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486dsfkjghyu2cf04"
|
||||
isVerified: false
|
||||
isUntrustworthy: false
|
||||
isContact: false
|
||||
onlineStatus: 1
|
||||
isAdmin: false
|
||||
nickName: "This girl I know from work"
|
||||
name: "annabelle"
|
||||
publicId: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc74f72cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486dsfkjghyu2cf04"
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
isMutualContact: false
|
||||
onlineStatus: true
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzXUQpAQBRGYWQvLNAyLJDV8C5qpiGnv/M9al5Ot27X0IUwhMYQGkNoDKGJCRlLH67bftx9X+ap/+P9VcxEDK
|
||||
ExhKZ4a9Uq3TZviZmIITSG0DRvlqcbqVbrlouZiCE0htD4h0hjCI0hNN5aNIbQGKKPxEzEEBpDaAyhMYTmDAAA//+gYCErzmCpCQAAAABJRU5ErkJggg=="
|
||||
isIdenticon: true
|
||||
ringSpecModel: [ ListElement {colorId: 11; segmentLength: 1},
|
||||
ListElement {colorId: 23; segmentLength: 5},
|
||||
ListElement {colorId: 23; segmentLength: 5},
|
||||
ListElement {colorId: 10; segmentLength: 4},
|
||||
ListElement {colorId: 15; segmentLength: 3},
|
||||
ListElement {colorId: 26; segmentLength: 2},
|
||||
ListElement {colorId: 29; segmentLength: 5} ]
|
||||
}
|
||||
ListElement {
|
||||
localNickname: "Mark Cuban"
|
||||
displayName: "mark.eth"
|
||||
pubKey: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc79872cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
isVerified: false
|
||||
isUntrustworthy: true
|
||||
isContact: true
|
||||
onlineStatus: 0
|
||||
nickName: "Mark Cuban"
|
||||
name: "mark.eth"
|
||||
publicId: "0x043a7ed0e8752236a4688563652fd0296453cef00a5dcddbe252dc79872cc1caa97a2b65e4a1a52d9c30a84c9966beaaaf6b333d659cbdd2e486b443ed1012cf04"
|
||||
trustIndicator: StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
isMutualContact: true
|
||||
onlineStatus: false
|
||||
icon: ""
|
||||
isAdmin: false
|
||||
isIdenticon: false
|
||||
ringSpecModel: [ ListElement {colorId: 0; segmentLength: 1},
|
||||
ListElement {colorId: 28; segmentLength: 1},
|
||||
ListElement {colorId: 31; segmentLength: 1},
|
||||
ListElement {colorId: 22; segmentLength: 4},
|
||||
ListElement {colorId: 28; segmentLength: 3},
|
||||
ListElement {colorId: 27; segmentLength: 5},
|
||||
ListElement {colorId: 7; segmentLength: 5},
|
||||
ListElement {colorId: 13; segmentLength: 1},
|
||||
ListElement {colorId: 25; segmentLength: 4}]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -948,20 +967,9 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
hasNotification: false
|
||||
notificationsCount: 0
|
||||
}
|
||||
ListElement {
|
||||
sectionId: "communitiesPortal"
|
||||
sectionType: 2
|
||||
name: "Communities Portal"
|
||||
active: false
|
||||
image: ""
|
||||
icon: "communities"
|
||||
color: ""
|
||||
hasNotification: false
|
||||
notificationsCount: 0
|
||||
}
|
||||
ListElement {
|
||||
sectionId: "wallet"
|
||||
sectionType: 3
|
||||
sectionType: 2
|
||||
name: "Wallet"
|
||||
active: false
|
||||
image: ""
|
||||
@@ -972,7 +980,7 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
}
|
||||
ListElement {
|
||||
sectionId: "browser"
|
||||
sectionType: 4
|
||||
sectionType: 3
|
||||
name: "Browser"
|
||||
active: false
|
||||
image: ""
|
||||
@@ -1298,186 +1306,4 @@ CExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2I
|
||||
selected: false
|
||||
}
|
||||
}
|
||||
|
||||
property ListModel featuredCommunitiesModel : ListModel {
|
||||
ListElement {
|
||||
name: "CryptoKitties";
|
||||
description: "A community of cat lovers, meow!";
|
||||
logo:"qrc:/images/CryptoKitties.png";
|
||||
members: 1045;
|
||||
categories: [];
|
||||
communityId: "341";
|
||||
available: true;
|
||||
popularity: 1;
|
||||
communityColor: "pink"
|
||||
}
|
||||
ListElement {
|
||||
name: "Friends with Benefits";
|
||||
description: "A group chat full of out favorite thinkers and creators.";
|
||||
logo:"qrc:/images/FriendsBenefits.png";
|
||||
members: 452;
|
||||
categories: [];
|
||||
communityId: "232";
|
||||
available: true;
|
||||
popularity: 2;
|
||||
communityColor: "grey"
|
||||
}
|
||||
ListElement {
|
||||
name: "Status Hi!!";
|
||||
description: "A new community description with long long long and repetitive repetitive repetitive repetitive explanation!!";
|
||||
logo:"qrc:/images/SNT.png";
|
||||
members: 89;
|
||||
categories: [];
|
||||
communityId: "223";
|
||||
available: true;
|
||||
popularity: 3
|
||||
communityColor: "blue"
|
||||
}
|
||||
}
|
||||
|
||||
property ListModel curatedCommunitiesModel : ListModel {
|
||||
ListElement {
|
||||
name: "Status.im";
|
||||
description: "Your portal to Web3. Secure wallet. dApp browser. Private messaging. All-in-one.";
|
||||
logo: "qrc:/images/SNT.png";
|
||||
banner: "qrc:/images/CommunityBanner1.png";
|
||||
members: 299500;
|
||||
activeUsers: 71400;
|
||||
categories: [];
|
||||
communityId: "1";
|
||||
available: true;
|
||||
popularity: 1
|
||||
isPrivate: true
|
||||
tokenLogo: "qrc:/images/SNT.png";
|
||||
}
|
||||
ListElement {
|
||||
name: "SuperRare";
|
||||
description: "The future of CryptoArt markets—a network governed by artists, collectors and curators.";
|
||||
logo:"qrc:/images/SR.png";
|
||||
banner: "qrc:/images/SuperRareCommunityBanner.png";
|
||||
members: 299500;
|
||||
activeUsers: 71400;
|
||||
categories: [];
|
||||
communityId: "2";
|
||||
available: true;
|
||||
popularity: 2
|
||||
isPrivate: true
|
||||
tokenLogo: "qrc:/images/SRToken.png";
|
||||
}
|
||||
ListElement {
|
||||
name: "Coinbase";
|
||||
description: "Jump start your crypto portfolio with the easiest place to buy and sell crypto. ";
|
||||
logo:"qrc:/images/Coinbase.png";
|
||||
banner: "qrc:/images/CoinBaseCommunityBanner.png";
|
||||
members: 4900000;
|
||||
activeUsers: 245600;
|
||||
categories: [];
|
||||
communityId: "3";
|
||||
available: true;
|
||||
popularity: 3
|
||||
isPrivate: false
|
||||
tokenLogo: "";
|
||||
}
|
||||
ListElement {
|
||||
name: "Rarible";
|
||||
description: "Multichain community-centric NFT marketplace. Create, sell and collect NFTs.";
|
||||
logo:"qrc:/images/Rarible.png";
|
||||
banner: "qrc:/images/RaribleCommunityBanner.png";
|
||||
members: 629200;
|
||||
activeUsers: 112100;
|
||||
categories: [];
|
||||
communityId: "4";
|
||||
available: true;
|
||||
popularity: 4
|
||||
isPrivate: true
|
||||
tokenLogo: "qrc:/images/RARI.png";
|
||||
}
|
||||
ListElement {
|
||||
name: "Spotify";
|
||||
description: "Listening is everything";
|
||||
logo:"qrc:/images/Spotify.png";
|
||||
banner: "qrc:/images/SpotifyCommunityBanner.png";
|
||||
members: 207500;
|
||||
activeUsers: 52200;
|
||||
categories: [];
|
||||
communityId: "5";
|
||||
available: true;
|
||||
popularity: 5
|
||||
isPrivate: false
|
||||
tokenLogo: "";
|
||||
}
|
||||
ListElement {
|
||||
name: "Dribbble";
|
||||
description: "Open source platform to write and distribute decentralized applications..";
|
||||
logo:"qrc:/images/Fluff.png";
|
||||
banner: "qrc:/images/DribbbleCommunityBanner.png";
|
||||
members: 2300000;
|
||||
activeUsers: 112100;
|
||||
categories: [];
|
||||
communityId: "6";
|
||||
available: true;
|
||||
popularity: 6
|
||||
isPrivate: false
|
||||
tokenLogo: "";
|
||||
}
|
||||
ListElement {
|
||||
name: "Status.im";
|
||||
description: "Your portal to Web3. Secure wallet. dApp browser. Private messaging. All-in-one.";
|
||||
logo:"qrc:/images/SNT.png";
|
||||
banner: ""
|
||||
members: 299500;
|
||||
activeUsers: 71400;
|
||||
categories: [];
|
||||
communityId: "7";
|
||||
available: true;
|
||||
popularity: 1
|
||||
isPrivate: false
|
||||
tokenLogo: "";
|
||||
}
|
||||
ListElement {
|
||||
name: "CryptoPunks";
|
||||
description: "Community description goes here. Community description goes here. Community description goes here. Community description goes here. Community description goes here. Community description goes here.";
|
||||
logo:"qrc:/images/CryptoPunks.png";
|
||||
banner: "";
|
||||
members: 4900;
|
||||
activeUsers: 245600;
|
||||
categories: [];
|
||||
communityId: "8";
|
||||
available: false;
|
||||
popularity: 8
|
||||
isPrivate: false
|
||||
tokenLogo: "";
|
||||
}
|
||||
ListElement {
|
||||
name: "Socks";
|
||||
description: "Community description goes here.";
|
||||
logo:"qrc:/images/Socks.png";
|
||||
banner: "";
|
||||
members: 4900;
|
||||
activeUsers: 245600;
|
||||
categories: [];
|
||||
communityId: "9";
|
||||
available: false;
|
||||
popularity: 9
|
||||
isPrivate: false
|
||||
tokenLogo: "";
|
||||
}
|
||||
}
|
||||
|
||||
property ListModel tagsModel : ListModel {
|
||||
ListElement { name: "gaming"; emoji: "🎮"}
|
||||
ListElement { name: "art"; emoji: "🖼️️"}
|
||||
ListElement { name: "crypto"; emoji: "💸"}
|
||||
ListElement { name: "nsfw"; emoji: "🍆"}
|
||||
ListElement { name: "markets"; emoji: "💎"}
|
||||
ListElement { name: "defi"; emoji: "📈"}
|
||||
ListElement { name: "travel"; emoji: "🚁"}
|
||||
ListElement { name: "web3"; emoji: "🗺"}
|
||||
ListElement { name: "sport"; emoji: "🎾"}
|
||||
ListElement { name: "food"; emoji: "🥑"}
|
||||
ListElement { name: "enviroment"; emoji: "☠️"}
|
||||
ListElement { name: "privacy"; emoji: "👻"}
|
||||
}
|
||||
|
||||
property var communityTags :{"Activism":"✊","Art":"🎨","Blockchain":"🔗","Books & blogs":"📚","Career":"💼","Collaboration":"🤝","Commerce":"🛒","Crypto":"Ξ","Culture":"🎎","DAO":"🚀","DIY":"🔨","DeFi":"📈","Design":"🧩","Education":"🎒","Entertainment":"🍿","Environment":"🌿","Event":"🗓","Fantasy":"🧙♂️","Fashion":"🧦","Food":"🌶","Gaming":"🎮","Global":"🌍","Health":"🧠","Hobby":"📐","Innovation":"🧪","Language":"📜","Lifestyle":"✨","Local":"📍","Love":"❤️","Markets":"💎","Movies & TV":"🎞","Music":"🎶","NFT":"🖼","NSFW":"🍆","News":"🗞","Non-profit":"🙏","Org":"🏢","Pets":"🐶","Play":"🎲","Podcast":"🎙️","Politics":"🗳️","Privacy":"👻","Product":"🍱","Psyche":"🍁","Security":"🔒","Social":"☕","Software dev":"👩💻","Sports":"⚽️","Tech":"📱","Travel":"🗺","Vehicles":"🚕","Web3":"🌐"}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 838 B |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 398 B |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 957 B |
|
Before Width: | Height: | Size: 1009 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 730 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 190 KiB |
@@ -12,8 +12,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
SandboxApp app(argc, argv);
|
||||
|
||||
qputenv("QT_QUICK_CONTROLS_HOVER_ENABLED", QByteArrayLiteral("1"));
|
||||
|
||||
app.setOrganizationName("Status");
|
||||
app.setOrganizationDomain("status.im");
|
||||
app.setApplicationName("Sandbox");
|
||||
|
||||
@@ -149,36 +149,36 @@ StatusWindow {
|
||||
spacing: 0
|
||||
|
||||
StatusListSectionHeadline { text: "StatusQ.Core" }
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "Icons"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title);
|
||||
}
|
||||
|
||||
StatusListSectionHeadline { text: "StatusQ.Layout" }
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "Layouts"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title.substring(0, title.length - 1));
|
||||
}
|
||||
|
||||
StatusListSectionHeadline { text: "StatusQ.Controls" }
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "Buttons"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "StatusSwitchTab"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page("StatusTabSwitch");
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "StatusChatCommandButton"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "Controls"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title);
|
||||
@@ -193,37 +193,37 @@ StatusWindow {
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "StatusInput"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "StatusSelect"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "StatusAccountSelector"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "StatusAssetSelector"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "StatusColorSelector"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "StatusWalletColorButton"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "StatusWalletColorSelect"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
@@ -239,22 +239,22 @@ StatusWindow {
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusListSectionHeadline { text: "StatusQ.Components" }
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "StatusAddress"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "List Items"
|
||||
selected: viewLoader.source.toString().includes(title.replace(/\s+/g, ''))
|
||||
onClicked: mainPageView.control(title.replace(/\s+/g, ''));
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "StatusChatInfoToolBar"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "Others"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.control(title);
|
||||
@@ -284,32 +284,18 @@ StatusWindow {
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusCommunityCard"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusCommunityTags"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusListSectionHeadline { text: "StatusQ.Popup" }
|
||||
StatusNavigationListItem {
|
||||
StatusNavigationListItem {
|
||||
title: "StatusPopupMenu"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
|
||||
StatusNavigationListItem {
|
||||
title: "StatusModal"
|
||||
selected: viewLoader.source.toString().includes("Popups")
|
||||
onClicked: mainPageView.control("Popups");
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusDialog"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title);
|
||||
}
|
||||
StatusListSectionHeadline { text: "StatusQ.Platform" }
|
||||
StatusNavigationListItem {
|
||||
title: "StatusMacNotification"
|
||||
@@ -326,11 +312,6 @@ StatusWindow {
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title, true);
|
||||
}
|
||||
StatusNavigationListItem {
|
||||
title: "StatusColorSpace"
|
||||
selected: viewLoader.source.toString().includes(title)
|
||||
onClicked: mainPageView.page(title, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,110 +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 {
|
||||
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
|
||||
StatusBaseText {
|
||||
text: qsTr("Thickness")
|
||||
}
|
||||
|
||||
StatusSlider {
|
||||
id: thicknessSlider
|
||||
from: colorSpace.width / 8
|
||||
to: colorSpace.width / 16
|
||||
value: colorSpace.width / 10
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: qsTr("Min saturate: ") + colorSpace.minSaturate.toFixed(2)
|
||||
}
|
||||
|
||||
StatusSlider {
|
||||
id: minSatSlider
|
||||
from: 0
|
||||
to: 0.5
|
||||
value: 0
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: qsTr("Max saturate: ") + colorSpace.maxSaturate.toFixed(2)
|
||||
}
|
||||
|
||||
StatusSlider {
|
||||
id: maxSatSlider
|
||||
from: 0.51
|
||||
to: 1.0
|
||||
value: 1.0
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: qsTr("Min value: ") + colorSpace.minValue.toFixed(2)
|
||||
}
|
||||
|
||||
StatusSlider {
|
||||
id: minValSlider
|
||||
from: 0
|
||||
to: 0.5
|
||||
value: 0
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: qsTr("Max value: ") + colorSpace.maxValue.toFixed(2)
|
||||
}
|
||||
|
||||
StatusSlider {
|
||||
id: maxValSlider
|
||||
from: 0.51
|
||||
to: 1.0
|
||||
value: 1.0
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusColorSpace {
|
||||
id: colorSpace
|
||||
color: "#ed77eb"
|
||||
thickness: thicknessSlider.value
|
||||
minSaturate: minSatSlider.value
|
||||
maxSaturate: maxSatSlider.value
|
||||
minValue: minValSlider.value
|
||||
maxValue: maxValSlider.value
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: qsTr("Color") + ": " + colorSpace.color
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: colorSpace.color
|
||||
implicitHeight: 48
|
||||
radius: 10
|
||||
Layout.fillWidth: true
|
||||
|
||||
StatusBaseText {
|
||||
anchors.centerIn: parent
|
||||
color: Theme.palette.white
|
||||
font.pixelSize: 15
|
||||
text: "Quick brown fox jumps over the lazy dog"
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "Randomize"
|
||||
onPressed: colorSpace.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Layouts 1.13
|
||||
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
import "../demoapp/data" 1.0
|
||||
|
||||
GridLayout {
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
function navigateToCommunity(communityID) {
|
||||
console.log("Clicked community: " + communityID)
|
||||
}
|
||||
}
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
columns: 2
|
||||
columnSpacing: 28
|
||||
rowSpacing: 28
|
||||
|
||||
Repeater {
|
||||
model: Models.curatedCommunitiesModel
|
||||
delegate: StatusCommunityCard {
|
||||
locale: "en"
|
||||
communityId: model.communityId
|
||||
loaded: model.available
|
||||
logo: model.logo
|
||||
banner: model.banner
|
||||
name: model.name
|
||||
description: model.description
|
||||
members: model.members
|
||||
activeUsers: model.activeUsers
|
||||
popularity: model.popularity
|
||||
isPrivate: model.isPrivate
|
||||
tokenLogo: model.tokenLogo
|
||||
categories: ListModel {
|
||||
ListElement { name: "Crypto"; emoji: "🔗"}
|
||||
ListElement { name: "Privacy"; emoji: "👻"}
|
||||
ListElement { name: "Social"; emoji: "☕"}
|
||||
}
|
||||
|
||||
onClicked: { d.navigateToCommunity(communityId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +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
|
||||
|
||||
import "../demoapp/data" 1.0
|
||||
|
||||
Item {
|
||||
|
||||
property int cntSelectedTags: 0
|
||||
property int maxSelectedTags: 4
|
||||
property ListModel tagsModel: ListModel {}
|
||||
|
||||
Component.onCompleted: {
|
||||
tagsModel.clear();
|
||||
for (const key of Object.keys(Models.communityTags)) {
|
||||
tagsModel.append({ name: key, emoji: Models.communityTags[key], selected: false });
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: column
|
||||
anchors.centerIn: parent
|
||||
width: 600
|
||||
height: 500
|
||||
spacing: 20
|
||||
|
||||
StatusInput {
|
||||
id: tagsFilter
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
label: qsTr("Select tags that will fit your Community")
|
||||
input.icon.name: "search"
|
||||
input.placeholderText: qsTr("Search tags")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusCommunityTags {
|
||||
filterString: tagsFilter.text
|
||||
model: tagsModel
|
||||
enabled: cntSelectedTags < maxSelectedTags
|
||||
onClicked: {
|
||||
cntSelectedTags++;
|
||||
item.selected = true;
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
StatusBaseText {
|
||||
text: qsTr("Selected tags")
|
||||
font.pixelSize: 15
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: cntSelectedTags + "/" + maxSelectedTags
|
||||
color: Theme.palette.baseColor1
|
||||
font.pixelSize: 13
|
||||
}
|
||||
}
|
||||
|
||||
StatusCommunityTags {
|
||||
model: tagsModel
|
||||
showOnlySelected: true
|
||||
onClicked: {
|
||||
cntSelectedTags--;
|
||||
item.selected = false;
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtQml.Models 2.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups.Dialog 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
StatusButton {
|
||||
text: "Content"
|
||||
onClicked: contentDialog.open()
|
||||
|
||||
StatusDialog {
|
||||
id: contentDialog
|
||||
|
||||
standardButtons: Dialog.ApplyRole
|
||||
|
||||
StatusBaseText {
|
||||
anchors.fill: parent
|
||||
text: "Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "Title and content"
|
||||
onClicked: titleContentDialog.open()
|
||||
|
||||
StatusDialog {
|
||||
id: titleContentDialog
|
||||
title: "Title"
|
||||
|
||||
StatusBaseText {
|
||||
anchors.fill: parent
|
||||
text: "Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "No buttons"
|
||||
onClicked: noButtonsDialog.open()
|
||||
|
||||
StatusDialog {
|
||||
id: noButtonsDialog
|
||||
title: "No buttons"
|
||||
|
||||
standardButtons: Dialog.NoButton
|
||||
|
||||
StatusBaseText {
|
||||
anchors.fill: parent
|
||||
text: "Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "Long title"
|
||||
onClicked: longTitleDialog.open()
|
||||
|
||||
StatusDialog {
|
||||
id: longTitleDialog
|
||||
title: "Long title long title Long title long title Long title long title"
|
||||
|
||||
StatusBaseText {
|
||||
anchors.fill: parent
|
||||
text: "Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "Long title elided"
|
||||
onClicked: longTitleElidedDialog.open()
|
||||
|
||||
StatusDialog {
|
||||
id: longTitleElidedDialog
|
||||
title: "Long title long title Long title long title Long title long title"
|
||||
|
||||
width: 400
|
||||
|
||||
StatusBaseText {
|
||||
anchors.fill: parent
|
||||
text: "Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "Title subtitle"
|
||||
onClicked: titleSubtitleDialog.open()
|
||||
|
||||
StatusDialog {
|
||||
id: titleSubtitleDialog
|
||||
title: "This title will be ignored"
|
||||
|
||||
header: StatusDialogHeader {
|
||||
headline.title: "Title"
|
||||
headline.subtitle: "Subtitle"
|
||||
|
||||
actions.closeButton.onClicked: titleSubtitleDialog.close()
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
anchors.fill: parent
|
||||
text: "Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "Auto adjustable"
|
||||
onClicked: autoAdjustableDialog.open()
|
||||
|
||||
StatusDialog {
|
||||
id: autoAdjustableDialog
|
||||
|
||||
header: StatusDialogHeader {
|
||||
headline.title: "Dialog size will auto adapt"
|
||||
headline.subtitle: "To conent size"
|
||||
|
||||
actions.closeButton.onClicked: autoAdjustableDialog.close()
|
||||
}
|
||||
|
||||
footer: StatusDialogFooter {
|
||||
leftButtons: ObjectModel {
|
||||
StatusRoundButton {
|
||||
icon.name: "arrow-left"
|
||||
onClicked: autoAdjustableDialogContent.implicitWidth -= 100
|
||||
}
|
||||
StatusRoundButton {
|
||||
icon.name: "arrow-right"
|
||||
onClicked: autoAdjustableDialogContent.implicitWidth += 100
|
||||
}
|
||||
}
|
||||
rightButtons: ObjectModel {
|
||||
StatusRoundButton {
|
||||
icon.name: "arrow-down"
|
||||
onClicked: autoAdjustableDialogContent.implicitHeight -= 100
|
||||
}
|
||||
StatusRoundButton {
|
||||
icon.name: "arrow-up"
|
||||
onClicked: autoAdjustableDialogContent.implicitHeight += 100
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: autoAdjustableDialogContent
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
implicitWidth: 200
|
||||
implicitHeight: 200
|
||||
|
||||
color: Theme.palette.primaryColor3
|
||||
|
||||
StatusBaseText {
|
||||
anchors.centerIn: parent
|
||||
text: "W: %1 H: %2\nIW: %3 IH: %4".arg(parent.width).arg(parent.height).arg(parent.implicitWidth).arg(parent.implicitHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "Complex dialog"
|
||||
onClicked: complexDialog.open()
|
||||
|
||||
StatusDialog {
|
||||
id: complexDialog
|
||||
|
||||
header: StatusDialogHeader {
|
||||
id: dialogHeader
|
||||
|
||||
headline.title: "Complex dialog"
|
||||
headline.subtitle: "identicon, title subtitle, custom actions"
|
||||
|
||||
leftComponent: StatusLetterIdenticon {
|
||||
name: dialogHeader.headline.title
|
||||
}
|
||||
|
||||
actions {
|
||||
infoButton.visible: true
|
||||
|
||||
customButtons: ObjectModel {
|
||||
StatusFlatRoundButton {
|
||||
icon.name: "warning"
|
||||
icon.width: 20
|
||||
icon.height: 20
|
||||
}
|
||||
}
|
||||
|
||||
closeButton.onClicked: complexDialog.close()
|
||||
}
|
||||
}
|
||||
|
||||
footer: StatusDialogFooter {
|
||||
leftButtons: ObjectModel {
|
||||
StatusRoundButton {
|
||||
icon.name: "arrow-left"
|
||||
}
|
||||
}
|
||||
rightButtons: ObjectModel {
|
||||
StatusButton {
|
||||
text: "Custom cancel action"
|
||||
type: StatusButton.Danger
|
||||
}
|
||||
StatusButton {
|
||||
text: "Custom approve action"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
StatusBaseText {
|
||||
text: "Content A"
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: "Content B"
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: "Content C"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
text: "Custom header/footer"
|
||||
onClicked: customHeaderAndFooter.open()
|
||||
|
||||
StatusDialog {
|
||||
id: customHeaderAndFooter
|
||||
title: "No buttons"
|
||||
|
||||
header: Rectangle {
|
||||
implicitHeight: customHeaderText.height * 2
|
||||
implicitWidth: customHeaderText.width * 2
|
||||
|
||||
border.width: 2
|
||||
color: Theme.palette.statusPopupMenu.hoverBackgroundColor
|
||||
|
||||
StatusBaseText {
|
||||
id: customHeaderText
|
||||
anchors.centerIn: parent
|
||||
text: "Custom header"
|
||||
}
|
||||
}
|
||||
|
||||
footer: Rectangle {
|
||||
implicitHeight: customHeaderText.height * 2
|
||||
implicitWidth: customHeaderText.width * 2
|
||||
|
||||
border.width: 2
|
||||
color: Theme.palette.statusPopupMenu.hoverBackgroundColor
|
||||
|
||||
StatusBaseText {
|
||||
id: customFooter
|
||||
anchors.centerIn: parent
|
||||
text: "Custom footer"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StatusBaseText {
|
||||
anchors.fill: parent
|
||||
text: "Content"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,21 +9,17 @@ Item {
|
||||
property ListModel asortedContacts: ListModel {
|
||||
ListElement {
|
||||
publicId: "0x0"
|
||||
name: "emily.eth"
|
||||
name: "Maria"
|
||||
icon: ""
|
||||
isIdenticon: false
|
||||
onlineStatus: 3
|
||||
isReadonly: false
|
||||
tagIcon: ""
|
||||
}
|
||||
ListElement {
|
||||
publicId: "0x1"
|
||||
name: "vitalikbuterin"
|
||||
name: "James"
|
||||
icon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
isIdenticon: false
|
||||
onlineStatus: 1
|
||||
isReadonly: false
|
||||
tagIcon: ""
|
||||
}
|
||||
ListElement {
|
||||
publicId: "0x2"
|
||||
@@ -31,17 +27,13 @@ Item {
|
||||
icon: ""
|
||||
isIdenticon: false
|
||||
onlineStatus: 2
|
||||
isReadonly: false
|
||||
tagIcon: ""
|
||||
}
|
||||
ListElement {
|
||||
publicId: "0x3"
|
||||
name: "carmen.eth"
|
||||
name: "Tracy"
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||
isIdenticon: true
|
||||
onlineStatus: 3
|
||||
isReadonly: true
|
||||
tagIcon: "crown"
|
||||
}
|
||||
ListElement {
|
||||
publicId: "0x4"
|
||||
@@ -49,8 +41,6 @@ Item {
|
||||
icon: ""
|
||||
isIdenticon: false
|
||||
onlineStatus: 3
|
||||
isReadonly: false
|
||||
tagIcon: ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,9 +35,6 @@ Item {
|
||||
onClose: {
|
||||
console.warn("toast closed: ", modelData.title)
|
||||
}
|
||||
onClicked: {
|
||||
console.warn("toast clicked")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,30 +43,5 @@
|
||||
<file>pages/StatusToastMessagePage.qml</file>
|
||||
<file>pages/StatusWizardStepperPage.qml</file>
|
||||
<file>pages/StatusTabBarButtonPage.qml</file>
|
||||
<file>pages/StatusColorSpacePage.qml</file>
|
||||
<file>images/CryptoKitties.png</file>
|
||||
<file>images/CryptoPunks.png</file>
|
||||
<file>images/Dragonerum.png</file>
|
||||
<file>images/FriendsBenefits.png</file>
|
||||
<file>images/logo-test-image.png</file>
|
||||
<file>images/P2PCrypto.png</file>
|
||||
<file>images/SNT.png</file>
|
||||
<file>images/Socks.png</file>
|
||||
<file>images/StatusPunks.png</file>
|
||||
<file>images/CommunityBanner1.png</file>
|
||||
<file>images/Coinbase.png</file>
|
||||
<file>images/CoinBaseCommunityBanner.png</file>
|
||||
<file>images/DribbbleCommunityBanner.png</file>
|
||||
<file>images/Ethereum.png</file>
|
||||
<file>images/EthereumCommunityBanner.png</file>
|
||||
<file>images/Fluff.png</file>
|
||||
<file>images/Rarible.png</file>
|
||||
<file>images/RaribleCommunityBanner.png</file>
|
||||
<file>images/Spotify.png</file>
|
||||
<file>images/SpotifyCommunityBanner.png</file>
|
||||
<file>images/SR.png</file>
|
||||
<file>images/SuperRareCommunityBanner.png</file>
|
||||
<file>images/RARI.png</file>
|
||||
<file>images/SRToken.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
QT += quick svg
|
||||
|
||||
CONFIG += c++11 warn_on qtquickcompiler
|
||||
CONFIG += resources_big
|
||||
|
||||
QML_IMPORT_PATH= $$PWD/../src
|
||||
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
QMAKE_LFLAGS += $$(LDFLAGS)
|
||||
|
||||
# You can make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import QtGraphicalEffects 1.14
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property Item mask
|
||||
property color color: "#F6F8FA"
|
||||
|
||||
Rectangle {
|
||||
id: gradient
|
||||
anchors.fill: parent
|
||||
visible: false
|
||||
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
SkeletonGradientStop { color: "transparent"; from: -3; }
|
||||
SkeletonGradientStop { color: "transparent"; from: -2; }
|
||||
SkeletonGradientStop { color: root.color; from: -1 ; }
|
||||
SkeletonGradientStop { color: "transparent"; from: 0; }
|
||||
SkeletonGradientStop { color: "transparent"; from: 1; }
|
||||
}
|
||||
}
|
||||
|
||||
OpacityMask {
|
||||
anchors.fill: parent
|
||||
source: gradient
|
||||
maskSource: root.mask
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import QtGraphicalEffects 1.14
|
||||
|
||||
/*
|
||||
TODO: This component should be implemented as inline component of `SkeletonAnimation.qml`
|
||||
when we use Qt > 5.15
|
||||
*/
|
||||
|
||||
GradientStop {
|
||||
id: root
|
||||
|
||||
property real from: 0
|
||||
|
||||
color: "transparent"
|
||||
|
||||
NumberAnimation on position {
|
||||
easing.type: Easing.Linear
|
||||
loops: Animation.Infinite
|
||||
running: visible
|
||||
from: root.from
|
||||
to: from + 4
|
||||
duration: 2000
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
module StatusQ.Animations
|
||||
|
||||
SkeletonAnimation 0.1 SkeletonAnimation.qml
|
||||
SkeletonGradientStop 0.1 SkeletonGradientStop.qml
|
||||
@@ -73,7 +73,6 @@ Item {
|
||||
duration: 150
|
||||
direction: RotationAnimation.Clockwise
|
||||
easing.type: Easing.InCubic
|
||||
running: visible
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
@@ -83,7 +82,6 @@ Item {
|
||||
duration: 150
|
||||
direction: RotationAnimation.Counterclockwise
|
||||
easing.type: Easing.OutCubic
|
||||
running: visible
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
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
|
||||
|
||||
Rectangle {
|
||||
id: statusChatToolBar
|
||||
implicitWidth: 518
|
||||
height: 56
|
||||
color: Theme.palette.statusAppLayout.backgroundColor
|
||||
|
||||
property alias chatInfoButton: statusChatInfoButton
|
||||
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()
|
||||
@@ -24,125 +26,150 @@ Item {
|
||||
signal membersButtonClicked()
|
||||
signal searchButtonClicked()
|
||||
|
||||
implicitWidth: 518
|
||||
implicitHeight: 60
|
||||
|
||||
onPopupMenuChanged: {
|
||||
if (!!popupMenu) {
|
||||
popupMenuSlot.sourceComponent = popupMenu
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
width: parent.width
|
||||
spacing: padding / 2
|
||||
StatusChatInfoButton {
|
||||
id: statusChatInfoButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 12
|
||||
width: Math.min(implicitWidth, parent.width - actionButtons.implicitWidth - anchors.leftMargin * 2)
|
||||
onClicked: statusChatToolBar.chatInfoButtonClicked()
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
sourceComponent: statusChatToolBar.toolbarComponent
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
||||
Layout.topMargin: padding
|
||||
Layout.leftMargin: padding
|
||||
Row {
|
||||
id: actionButtons
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 8
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: actionButtons
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignRight
|
||||
Layout.topMargin: padding
|
||||
Layout.rightMargin: padding
|
||||
spacing: 8
|
||||
StatusFlatRoundButton {
|
||||
id: membersButton
|
||||
width: 32
|
||||
height: 32
|
||||
icon.name: "group-chat"
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
onClicked: statusChatToolBar.membersButtonClicked()
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: searchButton
|
||||
width: 32
|
||||
height: 32
|
||||
icon.name: "search"
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
onClicked: statusChatToolBar.searchButtonClicked()
|
||||
// initializing the tooltip
|
||||
tooltip.text: qsTr("Members")
|
||||
tooltip.orientation: StatusToolTip.Orientation.Bottom
|
||||
tooltip.y: parent.height + 12
|
||||
}
|
||||
|
||||
// initializing the tooltip
|
||||
tooltip.text: qsTr("Search")
|
||||
tooltip.orientation: StatusToolTip.Orientation.Bottom
|
||||
tooltip.y: parent.height + 12
|
||||
}
|
||||
StatusFlatRoundButton {
|
||||
id: menuButton
|
||||
width: 32
|
||||
height: 32
|
||||
icon.name: "more"
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
visible: !!statusChatToolBar.popupMenu
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: membersButton
|
||||
width: 32
|
||||
height: 32
|
||||
icon.name: "group-chat"
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
onClicked: statusChatToolBar.membersButtonClicked()
|
||||
// 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
|
||||
|
||||
// initializing the tooltip
|
||||
tooltip.text: qsTr("Members")
|
||||
tooltip.orientation: StatusToolTip.Orientation.Bottom
|
||||
tooltip.y: parent.height + 12
|
||||
}
|
||||
property bool showMoreMenu: false
|
||||
onClicked: {
|
||||
menuButton.highlighted = true
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: menuButton
|
||||
width: 32
|
||||
height: 32
|
||||
icon.name: "more"
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
visible: !!statusChatToolBar.popupMenu
|
||||
let originalOpenHandler = popupMenuSlot.item.openHandler
|
||||
let originalCloseHandler = popupMenuSlot.item.closeHandler
|
||||
|
||||
// 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.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
|
||||
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()
|
||||
}
|
||||
|
||||
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()
|
||||
Loader {
|
||||
id: popupMenuSlot
|
||||
active: !!statusChatToolBar.popupMenu
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 24
|
||||
width: 1
|
||||
color: Theme.palette.directColor7
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: notificationButton.visible &&
|
||||
(menuButton.visible || membersButton.visible || searchButton.visible)
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: notificationButton
|
||||
width: 32
|
||||
height: 32
|
||||
|
||||
icon.name: "notification"
|
||||
icon.height: 21
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
|
||||
// initializing the tooltip
|
||||
tooltip.text: qsTr("Activity")
|
||||
tooltip.orientation: StatusToolTip.Orientation.Bottom
|
||||
tooltip.y: parent.height + 12
|
||||
|
||||
onClicked: statusChatToolBar.notificationButtonClicked()
|
||||
|
||||
StatusBadge {
|
||||
id: statusBadge
|
||||
|
||||
visible: value > 0
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.right
|
||||
anchors.topMargin: -3
|
||||
anchors.leftMargin: {
|
||||
if (statusBadge.value > 99) {
|
||||
return -22
|
||||
}
|
||||
if (statusBadge.value > 9) {
|
||||
return -21
|
||||
}
|
||||
return -18
|
||||
}
|
||||
|
||||
value: statusChatToolBar.notificationCount
|
||||
border.width: 2
|
||||
border.color: parent.hovered ? Theme.palette.baseColor2 : Theme.palette.statusAppLayout.backgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property int thickness: width * 0.1
|
||||
property real minSaturate: 0.0
|
||||
property real minValue: 0.0
|
||||
property real maxSaturate: 1.0
|
||||
property real maxValue: 1.0
|
||||
property color color: "red"
|
||||
property color rootColor: Qt.hsva(color.hsvHue, 1, 1, 1)
|
||||
|
||||
function pickColorFromHueGauge(x, y) {
|
||||
// Get angle of picked color
|
||||
let theta = Math.atan2(y - hueGauge.height / 2, x - hueGauge.width / 2) * 0.5 / Math.PI;
|
||||
if (theta < 0.0)
|
||||
theta += 1.0;
|
||||
|
||||
// Convert angle value to color
|
||||
return Qt.hsva(1 - theta, 1, 1, 1)
|
||||
}
|
||||
|
||||
function pickColorFromSatValRect(x, y) {
|
||||
// x for saturation, reversed y for value
|
||||
let sat = mapFromRange(Math.min(Math.max(x, 0), satValRect.width),
|
||||
minSaturate, maxSaturate, satValRect.width);
|
||||
let val = 1 - mapFromRange(Math.min(Math.max(y, 0), satValRect.height),
|
||||
1 - maxValue, 1 - minValue, satValRect.height);
|
||||
return Qt.hsva(rootColor.hsvHue, sat, val, 1);
|
||||
}
|
||||
|
||||
function angleOnHueGauge(pickingColor) {
|
||||
// color hue to angle
|
||||
return (1 - pickingColor.hsvHue) * 2 * Math.PI;
|
||||
}
|
||||
|
||||
// TODO: mapToRange & mapFromRange to helper js
|
||||
function mapToRange(value, minValue, maxValue, range) {
|
||||
return (value - minValue) / (maxValue - minValue) * range;
|
||||
}
|
||||
|
||||
function mapFromRange(pos, minValue, maxValue, range) {
|
||||
return pos / range * (maxValue - minValue) + minValue;
|
||||
}
|
||||
|
||||
onColorChanged: {
|
||||
// update root color if only we are not picking on satValRect
|
||||
if (!d.pickingSatVal)
|
||||
rootColor = Qt.hsva(color.hsvHue, 1, 1, 1)
|
||||
}
|
||||
|
||||
implicitWidth: 340
|
||||
implicitHeight: 340
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property bool pickingSatVal: false
|
||||
}
|
||||
|
||||
ConicalGradient {
|
||||
id: hueGauge
|
||||
anchors.fill: parent
|
||||
angle: 90.0
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.000; color: Qt.hsva(1.000, 1, 1, 1) }
|
||||
GradientStop { position: 0.167; color: Qt.hsva(0.833, 1, 1, 1) }
|
||||
GradientStop { position: 0.333; color: Qt.hsva(0.666, 1, 1, 1) }
|
||||
GradientStop { position: 0.500; color: Qt.hsva(0.500, 1, 1, 1) }
|
||||
GradientStop { position: 0.667; color: Qt.hsva(0.333, 1, 1, 1) }
|
||||
GradientStop { position: 0.833; color: Qt.hsva(0.166, 1, 1, 1) }
|
||||
GradientStop { position: 1.000; color: Qt.hsva(0.000, 1, 1, 1) }
|
||||
}
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: Item {
|
||||
width: root.width
|
||||
height: root.height
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: Math.min(width, height) / 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: hueArea
|
||||
|
||||
property bool pressedOnGauge: false
|
||||
|
||||
anchors.fill: parent
|
||||
preventStealing: true
|
||||
onPressed: {
|
||||
// Check we clicked on gauge
|
||||
let dist = Math.sqrt(Math.pow(width / 2 - mouseX, 2) +
|
||||
Math.pow(height / 2 - mouseY, 2));
|
||||
let radius = Math.min(width, height) / 2;
|
||||
if (dist < radius - thickness || dist > radius)
|
||||
return;
|
||||
|
||||
pressedOnGauge = true;
|
||||
pickRootColor();
|
||||
}
|
||||
onReleased: pressedOnGauge = false
|
||||
onPositionChanged: if (pressedOnGauge) pickRootColor()
|
||||
|
||||
function pickRootColor() {
|
||||
// Update both colors
|
||||
rootColor = pickColorFromHueGauge(mouseX, mouseY);
|
||||
color.hsvHue = rootColor.hsvHue;
|
||||
color.hsvSaturation = Math.min(maxSaturate, Math.max(minSaturate, color.hsvSaturation));
|
||||
color.hsvValue = Math.min(maxValue, Math.max(minValue, color.hsvValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: root.thickness
|
||||
radius: Math.min(width, height) / 2
|
||||
|
||||
color: Theme.palette.baseColor5
|
||||
|
||||
Rectangle {
|
||||
id: satValRect
|
||||
anchors.centerIn: parent
|
||||
width: parent.width * 0.55
|
||||
height: width
|
||||
border.color: Theme.palette.baseColor3
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop { position: -minSaturate; color: "white" }
|
||||
GradientStop { position: 2.0 - maxSaturate; color: rootColor }
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Vertical
|
||||
GradientStop { position: maxValue - 1; color: "transparent" }
|
||||
GradientStop { position: 1.0 + minValue; color: "black" }
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: satValArea
|
||||
anchors.fill: parent
|
||||
preventStealing: true
|
||||
onPressed: {
|
||||
d.pickingSatVal = true;
|
||||
pickColor();
|
||||
}
|
||||
onReleased: d.pickingSatVal = false
|
||||
onPositionChanged: pickColor()
|
||||
|
||||
function pickColor() {
|
||||
root.color = pickColorFromSatValRect(mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: satValLens
|
||||
x: mapToRange(root.color.hsvSaturation, minSaturate, maxSaturate,
|
||||
satValRect.width) - radius
|
||||
y: mapToRange(1 - root.color.hsvValue, 1 - maxValue, 1 - minValue,
|
||||
satValRect.height) - radius
|
||||
width: thickness * 1.3
|
||||
height: width
|
||||
radius: height / 2
|
||||
border.width: 2
|
||||
border.color: Theme.palette.baseColor3
|
||||
color: root.color
|
||||
visible: x + 1 >= -radius && x - 1 <= satValRect.width - radius &&
|
||||
y + 1 >= -radius && y - 1 <= satValRect.height - radius
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: hueLens
|
||||
|
||||
property real theta: angleOnHueGauge(rootColor);
|
||||
property real dist: (hueGauge.width - width) / 2 + thickness / 6;
|
||||
|
||||
anchors.centerIn: parent
|
||||
anchors.horizontalCenterOffset: dist * Math.cos(theta);
|
||||
anchors.verticalCenterOffset: dist * Math.sin(theta);
|
||||
width: thickness * 1.3
|
||||
height: width
|
||||
radius: height / 2
|
||||
border.width: 2
|
||||
border.color: Theme.palette.baseColor3
|
||||
color: rootColor
|
||||
}
|
||||
}
|
||||
@@ -1,469 +0,0 @@
|
||||
import QtQuick 2.13
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusCommunityCard
|
||||
\inherits Rectangle
|
||||
\inqmlmodule StatusQ.Components
|
||||
\since StatusQ.Components 0.1
|
||||
\brief It is a community card item that provides relevant information about a community model. Inherits \l{https://doc.qt.io/qt-5/qml-qtquick-rectangle.html}{Rectangle}.
|
||||
|
||||
The \c StatusCommunityCard is a community card clickable item that represents a data model. The data model is commonly a JavaScript array or a ListModel object.
|
||||
|
||||
Example of how the component looks like:
|
||||
\image status_community_card.png
|
||||
Example of how to use it:
|
||||
\qml
|
||||
StatusCommunityCard {
|
||||
locale: "en"
|
||||
communityId: model.communityId
|
||||
loaded: model.available
|
||||
logo: model.icon
|
||||
name: model.name
|
||||
description: model.description
|
||||
members: model.members
|
||||
popularity: model.popularity
|
||||
categories: model.categories
|
||||
|
||||
onClicked: { d.navigateToCommunity(communityId) }
|
||||
}
|
||||
\endqml
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
/*!
|
||||
\qmlproperty string StatusCommunityCard::communityId
|
||||
This property holds the community identifier value.
|
||||
*/
|
||||
property string communityId: ""
|
||||
/*!
|
||||
\qmlproperty bool StatusCommunityCard::loaded
|
||||
This property holds a boolean value that represents if the community information is loaded or not.
|
||||
*/
|
||||
property bool loaded: true
|
||||
/*!
|
||||
\qmlproperty url StatusCommunityCard::logo
|
||||
This property holds the community logo source.
|
||||
*/
|
||||
property url logo: ""
|
||||
/*!
|
||||
\qmlproperty string StatusCommunityCard::name
|
||||
This property holds the community name.
|
||||
*/
|
||||
property string name: ""
|
||||
/*!
|
||||
\qmlproperty string StatusCommunityCard::description
|
||||
This property holds the community description.
|
||||
*/
|
||||
property string description: ""
|
||||
/*!
|
||||
\qmlproperty int StatusCommunityCard::members
|
||||
This property holds the community members value.
|
||||
*/
|
||||
property int members: 0
|
||||
/*!
|
||||
\qmlproperty int StatusCommunityCard::activeUsers
|
||||
This property holds the community active users value.
|
||||
*/
|
||||
property int activeUsers: 0
|
||||
/*!
|
||||
\qmlproperty int StatusCommunityCard::popularity
|
||||
This property holds the community popularity (community rate).
|
||||
*/
|
||||
property int popularity: 0
|
||||
/*!
|
||||
\qmlproperty string StatusCommunityCard::categories
|
||||
This property holds the data that will be populated as the tags row of the community.
|
||||
|
||||
Here an example of the model roles expected:
|
||||
\qml
|
||||
categories: ListModel {
|
||||
ListElement { name: "gaming"; emoji: "🎮"; selected: false}
|
||||
ListElement { name: "art"; emoji: "🖼️️"; selected: false}
|
||||
ListElement { name: "crypto"; emoji: "💸"; selected: false}
|
||||
ListElement { name: "nsfw"; emoji: "🍆"; selected: false}
|
||||
ListElement { name: "markets"; emoji: "💎"; selected: false}
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
property ListModel categories: ListModel {}
|
||||
/*!
|
||||
\qmlproperty string StatusCommunityCard::locale
|
||||
This property holds the application locale used to give format to members number representation.
|
||||
If not provided, default value is "en".
|
||||
*/
|
||||
property string locale: "en"
|
||||
/*!
|
||||
\qmlproperty url StatusCommunityCard::banner
|
||||
This property holds the community banner image url.
|
||||
*/
|
||||
property url banner: ""
|
||||
/*!
|
||||
\qmlproperty color StatusCommunityCard::communityColor
|
||||
This property holds the community color.
|
||||
If not provided, default value in Light Theme is "#4360DF" and in Dark Theme is "#88B0FF".
|
||||
*/
|
||||
property color communityColor: Theme.palette.primaryColor1
|
||||
/*!
|
||||
\qmlproperty bool StatusCommunityCard::isPrivate
|
||||
This property holds if the community is private.
|
||||
If not provided, default value is false.
|
||||
*/
|
||||
property bool isPrivate: false
|
||||
/*!
|
||||
\qmlproperty url StatusCommunityCard::tokenLogo
|
||||
This property holds the image of the token needed if the community is private.
|
||||
*/
|
||||
property url tokenLogo: ""
|
||||
|
||||
/*!
|
||||
\qmlsignal StatusCommunityCard::clicked(string communityId)
|
||||
This signal is emitted when the card item is clicked.
|
||||
*/
|
||||
signal clicked(string communityId)
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property int cardWidth: 335
|
||||
property int bannerHeigth: 64
|
||||
property int cardHeigth: 190
|
||||
property int totalHeigth: 230
|
||||
property int margins: 12
|
||||
property int bannerRadius: 20
|
||||
property int cardRadius: 16
|
||||
property color cardColor: Theme.palette.indirectColor1
|
||||
property color fontColor: Theme.palette.directColor1
|
||||
property color loadingColor1: Theme.palette.baseColor5
|
||||
property color loadingColor2: Theme.palette.baseColor4
|
||||
|
||||
function numberFormat(number) {
|
||||
var res = number
|
||||
const million = 1000000
|
||||
const ks = 1000
|
||||
if(number > million) {
|
||||
res = number / million
|
||||
res = Number(number / million).toLocaleString(Qt.locale(root.locale), 'f', 1) + 'M'
|
||||
}
|
||||
else if(number > ks) {
|
||||
res = number / ks
|
||||
res = Number(number / ks).toLocaleString(Qt.locale(root.locale), 'f', 1) + 'K'
|
||||
}
|
||||
else
|
||||
res = Number(number).toLocaleString(Qt.locale(root.locale), 'f', 0)
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
implicitWidth: d.cardWidth
|
||||
implicitHeight: d.totalHeigth
|
||||
radius: d.bannerRadius
|
||||
color: "transparent"
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
source: root
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 2
|
||||
radius: sensor.containsMouse ? 30 : d.bannerRadius
|
||||
samples: 25
|
||||
spread: 0
|
||||
color: sensor.containsMouse ? Theme.palette.backdropColor : Theme.palette.dropShadow
|
||||
}
|
||||
|
||||
// Community banner:
|
||||
Item {
|
||||
id: banner
|
||||
anchors.top: parent.top
|
||||
width: d.cardWidth
|
||||
height: d.bannerHeigth
|
||||
Rectangle {
|
||||
id: mask
|
||||
anchors.fill: parent
|
||||
radius: d.bannerRadius
|
||||
color: root.loaded ? root.communityColor : d.loadingColor2
|
||||
}
|
||||
Image {
|
||||
id: image
|
||||
source: root.banner
|
||||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
fillMode: Image.PreserveAspectFit
|
||||
smooth: true
|
||||
visible: !root.loaded || !root.banner
|
||||
}
|
||||
OpacityMask {
|
||||
anchors.fill: image
|
||||
source: image
|
||||
maskSource: mask
|
||||
}
|
||||
}
|
||||
|
||||
// Community logo:
|
||||
Rectangle {
|
||||
z: content.z + 1
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 16
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 12
|
||||
width: 48
|
||||
height: width
|
||||
radius: width / 2
|
||||
color: root.loaded ? d.cardColor : d.loadingColor1
|
||||
|
||||
StatusRoundedImage {
|
||||
visible: root.loaded
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - 4
|
||||
height: width
|
||||
image.source: root.logo
|
||||
color: "transparent"
|
||||
}
|
||||
} // End of community logo
|
||||
|
||||
// Content card
|
||||
Rectangle {
|
||||
id: content
|
||||
z: banner.z + 1
|
||||
visible: root.loaded
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 40
|
||||
width: d.cardWidth
|
||||
height: d.cardHeigth
|
||||
color: d.cardColor
|
||||
radius: d.cardRadius
|
||||
clip: true
|
||||
// Community restriccions
|
||||
Rectangle {
|
||||
visible: root.isPrivate
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 8
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: anchors.topMargin
|
||||
width: 48
|
||||
height: 24
|
||||
color: d.loadingColor2
|
||||
radius: 200
|
||||
StatusIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.leftMargin: 6
|
||||
anchors.left: parent.left
|
||||
icon: "tiny/unlocked"
|
||||
width: 16
|
||||
height: 16
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
StatusRoundedImage {
|
||||
anchors.rightMargin: 2
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 20
|
||||
height: width
|
||||
image.source: root.tokenLogo
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
// Community info
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 32
|
||||
anchors.leftMargin: d.margins
|
||||
anchors.rightMargin: d.margins
|
||||
anchors.bottomMargin: d.margins
|
||||
clip: true
|
||||
spacing: 6
|
||||
StatusBaseText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: root.name
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 19
|
||||
color: d.fontColor
|
||||
}
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: root.description
|
||||
font.pixelSize: 15
|
||||
lineHeight: 1.2
|
||||
color: d.fontColor
|
||||
maximumLineCount: 2
|
||||
wrapMode: Text.WordWrap
|
||||
elide: Text.ElideRight
|
||||
clip: true
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 116
|
||||
anchors.leftMargin: d.margins
|
||||
anchors.rightMargin: d.margins
|
||||
anchors.bottomMargin: d.margins
|
||||
clip: true
|
||||
spacing: 18
|
||||
Row {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
spacing: 20
|
||||
// Members
|
||||
Row {
|
||||
height: membersTxt.height
|
||||
spacing: 4
|
||||
StatusIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon: "tiny/members"
|
||||
width: 16
|
||||
height: 16
|
||||
}
|
||||
StatusBaseText {
|
||||
id: membersTxt
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: d.numberFormat(root.members)
|
||||
font.pixelSize: 15
|
||||
color: d.fontColor
|
||||
}
|
||||
}
|
||||
// Active users:
|
||||
Row {
|
||||
height: activeUsersTxt.height
|
||||
spacing: 4
|
||||
StatusIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon: "tiny/flash"
|
||||
width: 14
|
||||
height: 14
|
||||
}
|
||||
StatusBaseText {
|
||||
id: activeUsersTxt
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: d.numberFormat(root.activeUsers)
|
||||
font.pixelSize: 15
|
||||
color: d.fontColor
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: Replace by `StatusListItemTagRow` - To be done!
|
||||
Row {
|
||||
visible: root.categories.count > 0
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
spacing: 8
|
||||
clip: true
|
||||
|
||||
Repeater {
|
||||
model: root.categories
|
||||
delegate: StatusListItemTag {
|
||||
border.color: Theme.palette.baseColor2
|
||||
color: "transparent"
|
||||
height: 24
|
||||
radius: 20
|
||||
closeButtonVisible: false
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // End of content card
|
||||
|
||||
// Loading card
|
||||
Rectangle {
|
||||
visible: !root.loaded
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 40
|
||||
width: d.cardWidth
|
||||
height: d.cardHeigth
|
||||
color: d.cardColor
|
||||
radius: d.cardRadius
|
||||
clip: true
|
||||
Rectangle {
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 8
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: anchors.topMargin
|
||||
width: 48
|
||||
height: 24
|
||||
color: d.loadingColor2
|
||||
radius: 200
|
||||
}
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 32
|
||||
anchors.margins: d.margins
|
||||
clip: true
|
||||
spacing: 9
|
||||
Rectangle {
|
||||
width: 84
|
||||
height: 16
|
||||
color: d.loadingColor1
|
||||
radius: 5
|
||||
}
|
||||
Rectangle {
|
||||
width: 311
|
||||
height: 16
|
||||
color: d.loadingColor1
|
||||
radius: 5
|
||||
}
|
||||
Rectangle {
|
||||
width: 271
|
||||
height: 16
|
||||
color: d.loadingColor1
|
||||
radius: 5
|
||||
}
|
||||
Row {
|
||||
Layout.topMargin: 22 - 9
|
||||
spacing: 16
|
||||
Repeater {
|
||||
model: 2
|
||||
delegate: Row {
|
||||
spacing: 4
|
||||
Rectangle {
|
||||
width: 14
|
||||
height: 14
|
||||
color: d.loadingColor1
|
||||
radius: width / 2
|
||||
}
|
||||
Rectangle {
|
||||
width: 50
|
||||
height: 12
|
||||
color: d.loadingColor2
|
||||
radius: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Row {
|
||||
Layout.topMargin: 21 - 9
|
||||
spacing: 8
|
||||
Repeater {
|
||||
model: 3
|
||||
delegate:
|
||||
Rectangle {
|
||||
width: 76
|
||||
height: 24
|
||||
color: d.loadingColor2
|
||||
radius: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // End of loading card
|
||||
|
||||
MouseArea {
|
||||
id: sensor
|
||||
enabled: root.loaded
|
||||
anchors.fill: parent
|
||||
cursorShape: root.loaded ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: root.clicked(root.communityId)
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string filterString
|
||||
property bool showOnlySelected: false
|
||||
property bool active: true
|
||||
|
||||
property alias model: repeater.model
|
||||
property alias contentWidth: flow.width
|
||||
|
||||
signal clicked(var item)
|
||||
|
||||
implicitWidth: flow.implicitWidth
|
||||
implicitHeight: flow.implicitHeight
|
||||
|
||||
Flow {
|
||||
id: flow
|
||||
anchors.centerIn: parent
|
||||
width: {
|
||||
let itemsWidth = 0;
|
||||
for (let i = 0; i < repeater.count; ++i) {
|
||||
itemsWidth += spacing + repeater.itemAt(i).width;
|
||||
}
|
||||
return Math.min(parent.width, itemsWidth);
|
||||
}
|
||||
spacing: 10
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
|
||||
delegate: StatusCommunityTag {
|
||||
emoji: model.emoji
|
||||
name: model.name
|
||||
visible: (root.showOnlySelected ? model.selected : !model.selected) &&
|
||||
(filterString == 0 || name.toUpperCase().indexOf(filterString.toUpperCase()) !== -1)
|
||||
width: visible ? implicitWidth : -10
|
||||
height: visible ? implicitHeight : 0
|
||||
removable: root.showOnlySelected && root.active
|
||||
onClicked: root.clicked(model)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ Image {
|
||||
id: root
|
||||
|
||||
property string emojiId: ""
|
||||
|
||||
|
||||
width: 14
|
||||
height: 14
|
||||
sourceSize.width: width
|
||||
|
||||
@@ -217,12 +217,12 @@ Rectangle {
|
||||
Transition {
|
||||
from: "COLLAPSED"
|
||||
to: "EXPANDED"
|
||||
NumberAnimation { properties: "height"; duration: 200; running: visible }
|
||||
NumberAnimation { properties: "height"; duration: 200 }
|
||||
},
|
||||
Transition {
|
||||
from: "EXPANDED"
|
||||
to: "COLLAPSED"
|
||||
NumberAnimation { properties: "height"; duration: 200; running: visible }
|
||||
NumberAnimation { properties: "height"; duration: 200 }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -82,7 +82,12 @@ Item {
|
||||
\qmlproperty rect StatusImageCropPanel::cropRect
|
||||
\sa StatusImageCrop::cropRect
|
||||
*/
|
||||
readonly property alias cropRect: cropEditor.cropRect
|
||||
property alias cropRect: cropEditor.cropRect
|
||||
/*!
|
||||
\qmlproperty rect StatusImageCropPanel::cropRect
|
||||
\sa StatusImageCrop::cropRect
|
||||
*/
|
||||
readonly property alias cropWindow: cropEditor.cropWindow
|
||||
/*!
|
||||
\qmlproperty real StatusImageCrop::scrollZoomFactor
|
||||
How fast is image scaled (zoomed) when using mouse scroll
|
||||
@@ -111,11 +116,16 @@ Item {
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property int referenceWindowWidth: 1000
|
||||
function updateAspectRatio(newAR) {
|
||||
if(root.sourceSize.width === 0 || root.sourceSize.height === 0)
|
||||
return
|
||||
cropEditor.setCropRect(cropEditor.fillContentInWindow(root.sourceSize, Qt.size(referenceWindowWidth, referenceWindowWidth / root.aspectRatio)))
|
||||
// Keep width and adjust height
|
||||
const eW = cropEditor.cropRect.width
|
||||
const w = (eW <= 0) ? cropEditor.sourceSize.width : eW
|
||||
const h = w/newAR
|
||||
const c = (eW <= 0)
|
||||
? Qt.point(cropEditor.sourceSize.width/2, cropEditor.sourceSize.height/2)
|
||||
: Qt.point(cropEditor.cropRect.x + w/2, cropEditor.cropRect.y + cropEditor.cropRect.height/2)
|
||||
const nR = Qt.rect(c.x - w/2, c.y-h/2, w, h)
|
||||
cropEditor.setCropRect(nR)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,6 @@ import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Animations 0.1
|
||||
import QtGraphicalEffects 1.14
|
||||
|
||||
import "private"
|
||||
|
||||
Rectangle {
|
||||
id: statusListItem
|
||||
@@ -31,8 +27,6 @@ Rectangle {
|
||||
property Component bottomDelegate
|
||||
property var tagsModel: []
|
||||
property Component tagsDelegate
|
||||
property bool loading: false
|
||||
property bool loadingFailed: false
|
||||
|
||||
property StatusIconSettings icon: StatusIconSettings {
|
||||
height: isLetterIdenticon ? 40 : 20
|
||||
@@ -81,7 +75,7 @@ Rectangle {
|
||||
property alias statusListItemTagsSlot: statusListItemTagsSlot
|
||||
property alias statusListItemInlineTagsSlot: statusListItemTagsSlotInline
|
||||
|
||||
signal clicked(string itemId, var mouse)
|
||||
signal clicked(string itemId)
|
||||
signal titleClicked(string titleId)
|
||||
|
||||
enum Type {
|
||||
@@ -131,7 +125,7 @@ Rectangle {
|
||||
preventStealing: true
|
||||
|
||||
onClicked: {
|
||||
statusListItem.clicked(statusListItem.itemId, mouse)
|
||||
statusListItem.clicked(statusListItem.itemId)
|
||||
}
|
||||
|
||||
StatusSmartIdenticon {
|
||||
@@ -140,7 +134,6 @@ Rectangle {
|
||||
anchors.leftMargin: statusListItem.leftPadding
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 12
|
||||
visible: !iconOrImageLoadingOverlay.visible
|
||||
image: statusListItem.image
|
||||
icon: statusListItem.icon
|
||||
name: statusListItem.title
|
||||
@@ -152,20 +145,6 @@ Rectangle {
|
||||
ringSettings: statusListItem.ringSettings
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: iconOrImageLoadingOverlay
|
||||
visible: statusListItem.loading || statusListItem.loadingFailed
|
||||
anchors.fill: iconOrImage
|
||||
radius: width / 2
|
||||
color: statusListItem.loadingFailed ? Theme.palette.dangerColor2 : Theme.palette.baseColor1
|
||||
|
||||
SkeletonAnimation {
|
||||
anchors.fill: parent
|
||||
mask: parent
|
||||
visible: statusListItem.loading && !statusListItem.loadingFailed
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusListItemTitleArea
|
||||
|
||||
@@ -185,29 +164,8 @@ Rectangle {
|
||||
|
||||
height: childrenRect.height
|
||||
|
||||
Rectangle {
|
||||
id: titleLoadingOverlay
|
||||
visible: statusListItem.loading || statusListItem.loadingFailed
|
||||
anchors {
|
||||
left: statusListItemTitle.left
|
||||
top: statusListItemTitle.top
|
||||
bottom: statusListItemTitle.bottom
|
||||
}
|
||||
|
||||
width: Math.max(95, statusListItemTitle.width)
|
||||
radius: 4
|
||||
color: statusListItem.loadingFailed ? Theme.palette.dangerColor2 : Theme.palette.baseColor1
|
||||
|
||||
SkeletonAnimation {
|
||||
anchors.fill: parent
|
||||
mask: parent
|
||||
visible: statusListItem.loading && !statusListItem.loadingFailed
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: statusListItemTitle
|
||||
opacity: titleLoadingOverlay.visible ? 0 : 1
|
||||
text: statusListItem.title
|
||||
font.pixelSize: 15
|
||||
height: visible ? contentHeight : 0
|
||||
@@ -277,10 +235,7 @@ Rectangle {
|
||||
width: parent.width
|
||||
text: statusListItem.subTitle
|
||||
font.pixelSize: 15
|
||||
color: statusListItem.loadingFailed ? Theme.palette.dangerColor1
|
||||
: !statusListItem.enabled || !statusListItem.tertiaryTitle
|
||||
? Theme.palette.baseColor1
|
||||
: Theme.palette.directColor1
|
||||
color: !statusListItem.enabled || !statusListItem.tertiaryTitle ? Theme.palette.baseColor1 : Theme.palette.directColor1
|
||||
height: visible ? contentHeight : 0
|
||||
visible: !!statusListItem.subTitle
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
|
||||
@@ -6,7 +6,7 @@ import StatusQ.Core.Theme 0.1
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
width: layout.width + layout.anchors.margins
|
||||
width: layout.width
|
||||
height: 30
|
||||
color: Theme.palette.primaryColor3
|
||||
radius: 15
|
||||
@@ -39,12 +39,13 @@ Rectangle {
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
|
||||
height: parent.height
|
||||
anchors.margins: 6
|
||||
spacing: 5
|
||||
|
||||
StatusSmartIdenticon {
|
||||
id: iconOrImage
|
||||
Layout.leftMargin: 4
|
||||
Layout.leftMargin: 5
|
||||
image: root.image
|
||||
icon: root.icon
|
||||
name: root.title
|
||||
@@ -65,6 +66,7 @@ Rectangle {
|
||||
color: Theme.palette.primaryColor1
|
||||
icon: "close-circle"
|
||||
visible: closeButtonVisible
|
||||
Layout.rightMargin: 5
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -11,7 +11,7 @@ StatusIcon {
|
||||
from: 0;
|
||||
to: 360;
|
||||
duration: 1200
|
||||
running: visible
|
||||
running: true
|
||||
loops: Animation.Infinite
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,40 +48,30 @@ StatusListItem {
|
||||
*/
|
||||
property string userName: ""
|
||||
/*!
|
||||
\qmlproperty string StatusMemberListItem::pubKey
|
||||
This property holds the chat public key of the member represented.
|
||||
\qmlproperty string StatusMemberListItem::chatKey
|
||||
This property holds the chat key of the member represented.
|
||||
*/
|
||||
property string pubKey: ""
|
||||
property string chatKey: ""
|
||||
/*!
|
||||
\qmlproperty string StatusMemberListItem::isContact
|
||||
This property holds if the member represented is contact.
|
||||
\qmlproperty string StatusMemberListItem::isMutualContact
|
||||
This property holds if the member represented is a mutual contact.
|
||||
*/
|
||||
property bool isContact: false
|
||||
property bool isMutualContact: false
|
||||
/*!
|
||||
\qmlproperty string StatusMemberListItem::isVerified
|
||||
This property holds if the member represented is verified contact.
|
||||
\qmlproperty string StatusMemberListItem::trustIndicator
|
||||
This property holds the trust indicator of the member represented. Possible values are:
|
||||
\list
|
||||
\li StatusContactVerificationIcons.TrustedType.None
|
||||
\li StatusContactVerificationIcons.TrustedType.Verified
|
||||
\li StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
\endlist
|
||||
*/
|
||||
property bool isVerified: false
|
||||
property var trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||
/*!
|
||||
\qmlproperty string StatusMemberListItem::isUntrustworthy
|
||||
This property holds if the member represented is untrustworthy.
|
||||
*/
|
||||
property bool isUntrustworthy: false
|
||||
/*!
|
||||
\qmlproperty string StatusMemberListItem::status
|
||||
\qmlproperty string StatusMemberListItem::isOnline
|
||||
This property holds the connectivity status of the member represented.
|
||||
0 - offline
|
||||
1 - online
|
||||
2 - doNotDisturb
|
||||
3 - idle
|
||||
*/
|
||||
// FIXME: move Constants.userStatus from status-desktop
|
||||
property int status: 0
|
||||
/*!
|
||||
\qmlproperty string StatusMemberListItem::isAdmin
|
||||
This property holds the admin status of the member represented.
|
||||
*/
|
||||
property bool isAdmin: false
|
||||
property bool isOnline: false
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
@@ -92,37 +82,33 @@ StatusListItem {
|
||||
if(root.userName !== "" && root.nickName !== "")
|
||||
compose = "(" + root.userName + ")"
|
||||
|
||||
if(compose !== "" && root.pubKey !== "")
|
||||
if(compose !== "" && root.chatKey !== "")
|
||||
// Composition
|
||||
compose += " • " + composeShortKeyChat(root.pubKey)
|
||||
compose += " • " + composeShortKeyChat(root.chatKey)
|
||||
|
||||
else if(root.pubKey !== "")
|
||||
compose = composeShortKeyChat(root.pubKey)
|
||||
else if(root.chatKey !== "")
|
||||
compose = composeShortKeyChat(root.chatKey)
|
||||
|
||||
return compose
|
||||
}
|
||||
|
||||
// Short keychat composition:
|
||||
function composeShortKeyChat(pubKey) {
|
||||
return pubKey.substring(0, 5) + "..." + pubKey.substring(pubKey.length - 3)
|
||||
function composeShortKeyChat(chatKey) {
|
||||
return chatKey.substring(0, 5) + "..." + chatKey.substring(chatKey.length - 3)
|
||||
}
|
||||
}
|
||||
|
||||
// root object settings:
|
||||
title: (root.nickName === "") ? root.userName : root.nickName
|
||||
statusListItemTitleIcons.sourceComponent: StatusContactVerificationIcons {
|
||||
isMutualContact: root.isContact
|
||||
trustIndicator: {
|
||||
if (root.isVerified) return StatusContactVerificationIcons.TrustedType.Verified
|
||||
else if (root.isUntrustworthy) return StatusContactVerificationIcons.TrustedType.Untrustworthy
|
||||
return StatusContactVerificationIcons.TrustedType.None
|
||||
}
|
||||
isMutualContact: root.isMutualContact
|
||||
trustIndicator: root.trustIndicator
|
||||
}
|
||||
subTitle: d.composeSubtitile()
|
||||
statusListItemSubTitle.font.pixelSize: 10
|
||||
icon.isLetterIdenticon: !root.image.source.toString()
|
||||
statusListItemIcon.badge.visible: true
|
||||
statusListItemIcon.badge.color: root.status === 1 ? Theme.palette.successColor1 : Theme.palette.baseColor1 // FIXME
|
||||
statusListItemIcon.badge.color: root.isOnline ? Theme.palette.successColor1 : Theme.palette.baseColor1
|
||||
color: sensor.containsMouse ? Theme.palette.baseColor2 : Theme.palette.baseColor4
|
||||
|
||||
// Default sizes / positions by design
|
||||
@@ -138,12 +124,4 @@ StatusListItem {
|
||||
statusListItemIcon.badge.border.width: 2
|
||||
statusListItemIcon.badge.implicitHeight: 12 // 8 px + 2 px * 2 borders
|
||||
statusListItemIcon.badge.implicitWidth: 12 // 8 px + 2 px * 2 borders
|
||||
components: [
|
||||
StatusIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: root.isAdmin
|
||||
icon: "crown"
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ StatusListItem {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
onClicked: statusNavigationListItem.clicked(statusNavigationListItem.itemId, mouse)
|
||||
onClicked: statusNavigationListItem.clicked(mouse)
|
||||
}
|
||||
|
||||
components: [
|
||||
|
||||
@@ -28,19 +28,11 @@ Rectangle {
|
||||
id: image
|
||||
width: statusRoundImage.width
|
||||
height: statusRoundImage.height
|
||||
sourceSize.width: parent.width * 2
|
||||
sourceSize.height: parent.height * 2
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
|
||||
onSourceChanged: {
|
||||
if (sourceSize.width < width || sourceSize.height < height) {
|
||||
sourceSize = Qt.binding(function() {
|
||||
return Qt.size(width * 2, height * 2)
|
||||
})
|
||||
}
|
||||
else {
|
||||
sourceSize = undefined
|
||||
}
|
||||
}
|
||||
cache: true
|
||||
}
|
||||
|
||||
Loader {
|
||||
|
||||
@@ -5,7 +5,6 @@ import QtGraphicalEffects 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusTagSelector
|
||||
@@ -26,21 +25,24 @@ import StatusQ.Controls 0.1
|
||||
anchors.centerIn: parent
|
||||
namesModel: ListModel {
|
||||
ListElement {
|
||||
pubKey: "0x0"
|
||||
publicId: "0x0"
|
||||
name: "Maria"
|
||||
icon: ""
|
||||
isIdenticon: false
|
||||
onlineStatus: 3
|
||||
}
|
||||
ListElement {
|
||||
pubKey: "0x1"
|
||||
publicId: "0x1"
|
||||
name: "James"
|
||||
icon: "https://pbs.twimg.com/profile_images/1369221718338895873/T_5fny6o_400x400.jpg"
|
||||
isIdenticon: false
|
||||
onlineStatus: 1
|
||||
}
|
||||
ListElement {
|
||||
pubKey: "0x2"
|
||||
publicId: "0x2"
|
||||
name: "Paul"
|
||||
icon: ""
|
||||
isIdenticon: false
|
||||
onlineStatus: 2
|
||||
}
|
||||
}
|
||||
@@ -57,6 +59,10 @@ import StatusQ.Controls 0.1
|
||||
Item {
|
||||
id: root
|
||||
|
||||
implicitWidth: 448
|
||||
implicitHeight: (104 + contactsLabel.height + contactsLabel.anchors.topMargin + (userListView.model.count * 64)) > root.maxHeight ? root.maxHeight :
|
||||
(104 + contactsLabel.height + contactsLabel.anchors.topMargin + (userListView.model.count * 64))
|
||||
|
||||
/*!
|
||||
\qmlproperty real StatusTagSelector::maxHeight
|
||||
This property holds the maximum height of the component.
|
||||
@@ -94,26 +100,19 @@ Item {
|
||||
property int nameCountLimit: 5
|
||||
|
||||
/*!
|
||||
\qmlproperty var StatusTagSelector::ringSpecModelGetter
|
||||
\qmlproperty var StatusTagSelector::ringSpecModel
|
||||
This property holds the function to calculate the ring spec model
|
||||
based on the public key.
|
||||
*/
|
||||
property var ringSpecModelGetter: (pubKey) => { /*return ringSpecModel*/ }
|
||||
|
||||
/*!
|
||||
\qmlproperty var StatusTagSelector::compressKeyGetter
|
||||
\qmlproperty var StatusTagSelector::compressKey
|
||||
This property holds the function to calculate the compressed
|
||||
key based on the public key.
|
||||
*/
|
||||
property var compressedKeyGetter: (pubKey) => { /*return compressed key;*/ }
|
||||
|
||||
/*!
|
||||
\qmlproperty var StatusTagSelector::colorIdForPubkeyGetter
|
||||
This property holds the function to calculate the color Id
|
||||
based on the public key.
|
||||
*/
|
||||
property var colorIdForPubkeyGetter: (pubKey) => { /*return color Id;*/ }
|
||||
|
||||
/*!
|
||||
\qmlproperty ListModel StatusTagSelector::sortedList
|
||||
This property holds the sorted list model.
|
||||
@@ -124,18 +123,6 @@ Item {
|
||||
This property holds the asorted names model.
|
||||
*/
|
||||
property ListModel namesModel: ListModel { }
|
||||
/*!
|
||||
\qmlproperty bool StatusTagSelector::showSortedListOnlyWhenText
|
||||
This property will decide if the sorted list view info is displayed before entering some text in the input or after.
|
||||
By default is set to false.
|
||||
*/
|
||||
property bool showSortedListOnlyWhenText: false
|
||||
/*!
|
||||
\qmlproperty bool StatusTagSelector::orderByReadonly
|
||||
This property will decide if the displayed tag names will be ordered from left to right starting with the items that are marked as `isReadonly`.
|
||||
By default is set to true (readonly names at left).
|
||||
*/
|
||||
property bool orderByReadonly: true
|
||||
|
||||
/*!
|
||||
\qmlmethod
|
||||
@@ -150,12 +137,9 @@ Item {
|
||||
\qmlmethod
|
||||
This function is used to insert a new tag.
|
||||
*/
|
||||
function insertTag(name, id, isReadonly, tagIcon) {
|
||||
if (!find(namesModel, function(item) { return item.pubKey === id }) && namesModel.count < root.nameCountLimit) {
|
||||
if(orderByReadonly && isReadonly)
|
||||
namesModel.insert(0, {"name": name, "pubKey": id, "isReadonly": !!isReadonly, "tagIcon": tagIcon ? tagIcon : ""});
|
||||
else
|
||||
namesModel.insert(namesModel.count, {"name": name, "pubKey": id, "isReadonly": !!isReadonly, "tagIcon": tagIcon ? tagIcon : ""});
|
||||
function insertTag(name, id) {
|
||||
if (!find(namesModel, function(item) { return item.publicId === id }) && namesModel.count < root.nameCountLimit) {
|
||||
namesModel.insert(namesModel.count, {"name": name, "publicId": id});
|
||||
addMember(id);
|
||||
edit.clear();
|
||||
}
|
||||
@@ -170,19 +154,13 @@ Item {
|
||||
if (text !== "") {
|
||||
for (var i = 0; i < inputModel.count; i++ ) {
|
||||
var entry = inputModel.get(i);
|
||||
if (entry.displayName.toLowerCase().includes(text.toLowerCase()) &&
|
||||
!find(namesModel, function(item) { return item.name === entry.displayName })) {
|
||||
sortedList.append({"pubKey": entry.pubKey,
|
||||
"displayName": entry.displayName,
|
||||
"localNickname": entry.localNickname,
|
||||
"isVerified": entry.isVerified,
|
||||
"isUntrustworthy": entry.isUntrustworthy,
|
||||
"isContact": entry.isMutualContact,
|
||||
"ringSpecModel": entry.ringSpecModel,
|
||||
"icon": entry.icon,
|
||||
"onlineStatus": entry.onlineStatus,
|
||||
"tagIcon": entry.tagIcon ? entry.tagIcon : "",
|
||||
"isReadonly": !!entry.isReadonly});
|
||||
if (entry.name.toLowerCase().includes(text.toLowerCase()) &&
|
||||
!find(namesModel, function(item) { return item.name === entry.name })) {
|
||||
sortedList.append({"publicId": entry.publicId, "name": entry.name,
|
||||
"nickName": entry.nickName, "trustIndicator": entry.trustIndicator,
|
||||
"isMutualContact": entry.isMutualContact, "ringSpecModel": entry.ringSpecModel,
|
||||
"icon": entry.icon, "isIdenticon": entry.isIdenticon,
|
||||
"onlineStatus": entry.onlineStatus});
|
||||
userListView.model = sortedList;
|
||||
}
|
||||
}
|
||||
@@ -203,36 +181,6 @@ Item {
|
||||
*/
|
||||
signal removeMember(string memberId)
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property real suggestionContainerHeight: suggestionsContainer.visible ? contactsLabel.height + contactsLabel.anchors.topMargin +
|
||||
suggestionsContainer.anchors.topMargin + suggestionsContainer.anchors.bottomMargin +
|
||||
2 * bgRect.anchors.margins +
|
||||
userListView.anchors.topMargin + userListView.anchors.bottomMargin +
|
||||
(userListView.model.count * 64): 0
|
||||
|
||||
function orderNamesModel() {
|
||||
if(root.orderByReadonly) {
|
||||
for(var i = 0; i < namesModel.count; i++) {
|
||||
var entry = namesModel.get(i)
|
||||
if(entry.isReadonly) {
|
||||
namesModel.move(i, 0, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
implicitWidth: 448
|
||||
implicitHeight: (tagSelectorRect.height + d.suggestionContainerHeight) > root.maxHeight ? root.maxHeight : (tagSelectorRect.height + d.suggestionContainerHeight)
|
||||
|
||||
onOrderByReadonlyChanged: { d.orderNamesModel() }
|
||||
Component.onCompleted: {
|
||||
// Component initialization:
|
||||
d.orderNamesModel()
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: tagSelectorRect
|
||||
width: parent.width
|
||||
@@ -246,15 +194,14 @@ Item {
|
||||
spacing: 8
|
||||
StatusBaseText {
|
||||
Layout.preferredWidth: 22
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
color: Theme.palette.baseColor1
|
||||
text: root.toLabelText
|
||||
visible: (parent.width>22)
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.preferredWidth: (parent.width - 177) > 0 ? ((namesList.contentWidth > (parent.width - 177)) ?
|
||||
(parent.width - 177) : namesList.contentWidth) : 0
|
||||
Layout.preferredWidth: (namesList.contentWidth > (parent.width - 177)) ?
|
||||
(parent.width - 177) : namesList.contentWidth
|
||||
implicitHeight: 30
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: (namesList.count > 0)
|
||||
@@ -275,14 +222,35 @@ Item {
|
||||
}
|
||||
onWidthChanged: { scrollToEnd(); }
|
||||
onCountChanged: { scrollToEnd(); }
|
||||
delegate: StatusTagItem {
|
||||
isReadonly: model.isReadonly
|
||||
text: model.name
|
||||
icon: model.tagIcon
|
||||
|
||||
onClicked: {
|
||||
removeMember(model.pubKey);
|
||||
namesModel.remove(index, 1);
|
||||
delegate: Rectangle {
|
||||
id: nameDelegate
|
||||
width: (nameText.contentWidth + 34)
|
||||
height: 30
|
||||
color: mouseArea.containsMouse ? Theme.palette.miscColor1 : Theme.palette.primaryColor1
|
||||
radius: 8
|
||||
StatusBaseText {
|
||||
id: nameText
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 8
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Theme.palette.indirectColor1
|
||||
text: name
|
||||
}
|
||||
StatusIcon {
|
||||
anchors.left: nameText.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Theme.palette.indirectColor1
|
||||
icon: "close"
|
||||
}
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
removeMember(publicId);
|
||||
namesModel.remove(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,20 +267,16 @@ Item {
|
||||
font.family: Theme.palette.baseFont.name
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 44
|
||||
visible: (parent.width>22)
|
||||
Keys.onPressed: {
|
||||
if ((event.key === Qt.Key_Backspace || event.key === Qt.Key_Escape)
|
||||
&& getText(cursorPosition, (cursorPosition-1)) === ""
|
||||
&& (namesList.count-1) >= 0) {
|
||||
removeMember(namesModel.get(namesList.count-1).pubKey);
|
||||
removeMember(namesModel.get(namesList.count-1).publicId);
|
||||
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,
|
||||
sortedList.get(userListView.currentIndex).pubKey,
|
||||
sortedList.get(userListView.currentIndex).isReadonly,
|
||||
sortedList.get(userListView.currentIndex).tagIcon);
|
||||
}
|
||||
root.insertTag(sortedList.get(userListView.currentIndex).name, sortedList.get(userListView.currentIndex).publicId);
|
||||
}
|
||||
}
|
||||
Keys.onUpPressed: { userListView.decrementCurrentIndex(); }
|
||||
Keys.onDownPressed: { userListView.incrementCurrentIndex(); }
|
||||
@@ -353,8 +317,7 @@ Item {
|
||||
bottomMargin: 16//Style.current.padding
|
||||
}
|
||||
clip: true
|
||||
visible: (!root.showSortedListOnlyWhenText && ((root.sortedList.count > 0) || (edit.text === ""))) ||
|
||||
((edit.text !== "") && (root.sortedList.count > 0))
|
||||
visible: ((edit.text === "") || (root.sortedList.count > 0))
|
||||
x: ((root.namesModel.count > 0) && (root.sortedList.count > 0) && ((edit.x + 8) <= (root.width - suggestionsContainer.width)))
|
||||
? (edit.x + 8) : 0
|
||||
background: Rectangle {
|
||||
@@ -398,27 +361,25 @@ Item {
|
||||
height: visible ? 64 : 0
|
||||
visible: {
|
||||
for (let i = 0; i < namesModel.count; i++) {
|
||||
if (namesModel.get(i).pubKey === model.pubKey) {
|
||||
if (namesModel.get(i).publicId === model.publicId) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
nickName: model.localNickname
|
||||
userName: model.displayName
|
||||
pubKey: root.compressedKeyGetter(model.pubKey)
|
||||
isVerified: model.isVerified
|
||||
isUntrustworthy: model.isUntrustworthy
|
||||
isContact: model.isContact
|
||||
nickName: model.nickName
|
||||
userName: model.name
|
||||
chatKey: root.compressedKeyGetter(model.publicId)
|
||||
trustIndicator: model.trustIndicator
|
||||
isMutualContact: model.isMutualContact
|
||||
image.source: model.icon
|
||||
image.isIdenticon: false
|
||||
icon.color: Theme.palette.userCustomizationColors[root.colorIdForPubkeyGetter(model.pubKey)]
|
||||
status: model.onlineStatus
|
||||
image.isIdenticon: model.isIdenticon
|
||||
isOnline: model.onlineStatus
|
||||
statusListItemIcon.badge.border.color: sensor.containsMouse ? Theme.palette.baseColor2 : Theme.palette.baseColor4
|
||||
ringSettings.ringSpecModel: root.ringSpecModelGetter(model.pubKey)
|
||||
ringSettings.ringSpecModel: root.ringSpecModelGetter(publicId)
|
||||
color: (sensor.containsMouse || highlighted) ? Theme.palette.baseColor2 : "transparent"
|
||||
onClicked: {
|
||||
root.insertTag(model.displayName, model.pubKey, model.isAdmin, model.isAdmin ? "crown" : "");
|
||||
root.insertTag(model.name, model.publicId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,11 +125,6 @@ Control {
|
||||
root.open = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlsignal
|
||||
This signal is emitted when the ToastMessage is clicked.
|
||||
*/
|
||||
signal clicked()
|
||||
/*!
|
||||
\qmlsignal
|
||||
This signal is emitted when the ToastMessage is closed (after animation).
|
||||
@@ -219,9 +214,6 @@ Control {
|
||||
onMouseXChanged: {
|
||||
root.open = (mouseX < (root.width/3));
|
||||
}
|
||||
onClicked: {
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -115,7 +115,6 @@ Rectangle {
|
||||
properties: "scale";
|
||||
duration: 100;
|
||||
easing.type: Easing.InOutQuad
|
||||
running: visible
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,3 @@ StatusTagSelector 0.1 StatusTagSelector.qml
|
||||
StatusToastMessage 0.1 StatusToastMessage.qml
|
||||
StatusWizardStepper 0.1 StatusWizardStepper.qml
|
||||
StatusImageCropPanel 0.1 StatusImageCropPanel.qml
|
||||
StatusColorSpace 0.0 StatusColorSpace.qml
|
||||
StatusCommunityCard 0.1 StatusCommunityCard.qml
|
||||
StatusCommunityTags 0.1 StatusCommunityTags.qml
|
||||
|
||||
@@ -26,7 +26,6 @@ Item {
|
||||
property var assetFound
|
||||
property double minRequiredAssetBalance: 0
|
||||
property int dropdownWidth: width
|
||||
property int chainId: 0
|
||||
property alias dropdownAlignment: select.menuAlignment
|
||||
property bool isValid: true
|
||||
property bool readOnly: false
|
||||
@@ -47,7 +46,7 @@ Item {
|
||||
if (showBalanceForAssetSymbol == "" || minRequiredAssetBalance == 0 || !assetFound) {
|
||||
return root.isValid
|
||||
}
|
||||
root.isValid = assetFound.totalBalance >= minRequiredAssetBalance
|
||||
root.isValid = assetFound.balance >= minRequiredAssetBalance
|
||||
return root.isValid
|
||||
}
|
||||
|
||||
@@ -68,7 +67,7 @@ Item {
|
||||
textSelectedAddressFiatBalance.text = selectedAccount.currencyBalance + " " + currency.toUpperCase()
|
||||
}
|
||||
if (selectedAccount.assets && showBalanceForAssetSymbol) {
|
||||
assetFound = Utils.findAssetByChainAndSymbol(root.chainId, selectedAccount.assets, showBalanceForAssetSymbol)
|
||||
assetFound = Utils.findAssetBySymbol(selectedAccount.assets, showBalanceForAssetSymbol)
|
||||
if (!assetFound) {
|
||||
console.warn("Cannot find asset '", showBalanceForAssetSymbol, "'. Ensure this asset has been added to the token list.")
|
||||
}
|
||||
@@ -83,7 +82,7 @@ Item {
|
||||
if (!assetFound) {
|
||||
return
|
||||
}
|
||||
txtAssetBalance.text = root.assetBalanceTextFn(assetFound.totalBalance)
|
||||
txtAssetBalance.text = root.assetBalanceTextFn(assetFound.balance)
|
||||
txtAssetSymbol.text = " " + assetFound.symbol
|
||||
}
|
||||
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusActivityCenterButton
|
||||
\inherits StatusFlatRoundButton
|
||||
\inqmlmodule StatusQ.Controls
|
||||
\since StatusQ.Controls 0.1
|
||||
\brief The StatusActivityCenterButton provides the button for Activity Center popup
|
||||
|
||||
Example of how to use it:
|
||||
|
||||
\qml
|
||||
StatusActivityCenterButton {
|
||||
unreadNotificationsCount: activityCenter.unreadNotificationsCount
|
||||
onClicked: activityCenterPopup.open()
|
||||
}
|
||||
\endqml
|
||||
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: notificationButton
|
||||
|
||||
/*!
|
||||
\qmlproperty int StatusActivityCenterButton::unreadNotificationsCount
|
||||
This property holds the count of notifications.
|
||||
*/
|
||||
property alias unreadNotificationsCount: statusBadge.value
|
||||
|
||||
icon.name: "notification"
|
||||
icon.height: 21
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
|
||||
// initializing the tooltip
|
||||
tooltip.text: qsTr("Activity")
|
||||
tooltip.orientation: StatusToolTip.Orientation.Bottom
|
||||
tooltip.y: parent.height + 12
|
||||
|
||||
StatusBadge {
|
||||
id: statusBadge
|
||||
|
||||
visible: value > 0
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.right
|
||||
anchors.topMargin: -3
|
||||
anchors.leftMargin: {
|
||||
if (statusBadge.value > 99) {
|
||||
return -22
|
||||
}
|
||||
if (statusBadge.value > 9) {
|
||||
return -21
|
||||
}
|
||||
return -18
|
||||
}
|
||||
border.width: 2
|
||||
border.color: parent.hovered ? Theme.palette.baseColor2 : Theme.palette.statusAppLayout.backgroundColor
|
||||
}
|
||||
}
|
||||
@@ -116,12 +116,12 @@ Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
StatusBaseText {
|
||||
font.pixelSize: 15
|
||||
text: parseFloat(totalBalance).toFixed(4) + " " + symbol
|
||||
text: parseFloat(balance).toFixed(4) + " " + symbol
|
||||
}
|
||||
StatusBaseText {
|
||||
font.pixelSize: 15
|
||||
anchors.right: parent.right
|
||||
text: getCurrencyBalanceString(totalCurrencyBalance)
|
||||
text: getCurrencyBalanceString(currencyBalance)
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
}
|
||||
@@ -130,14 +130,14 @@ Item {
|
||||
}
|
||||
Component.onCompleted: {
|
||||
if(index === 0 ) {
|
||||
selectedAsset = { name: name, symbol: symbol, totalBalance: totalBalance, totalCurrencyBalance: totalCurrencyBalance}
|
||||
selectedAsset = { name: name, symbol: symbol, address: address, balance: balance, currencyBalance: currencyBalance}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
anchors.fill: itemContainer
|
||||
onClicked: {
|
||||
selectedAsset = {name: name, symbol: symbol, totalBalance: totalBalance, totalCurrencyBalance: totalCurrencyBalance}
|
||||
selectedAsset = {name: name, symbol: symbol, address: address, balance: balance, currencyBalance: currencyBalance}
|
||||
select.selectMenu.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import QtQuick 2.14
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
|
||||
Rectangle {
|
||||
id: statusBaseButton
|
||||
@@ -87,16 +86,14 @@ Rectangle {
|
||||
radius: size !== StatusBaseButton.Size.Tiny ? 8 : 6
|
||||
|
||||
color: {
|
||||
if (statusBaseButton.enabled)
|
||||
if (statusBaseButton.enabled) {
|
||||
return sensor.containsMouse || highlighted ? hoverColor
|
||||
: normalColor;
|
||||
return disaledColor
|
||||
: normalColor
|
||||
} else {
|
||||
return disaledColor
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
readonly property color textColor: statusBaseButton.enabled ? statusBaseButton.textColor : statusBaseButton.disabledTextColor
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: sensor
|
||||
@@ -105,16 +102,17 @@ Rectangle {
|
||||
|
||||
cursorShape: loading ? Qt.ArrowCursor
|
||||
: Qt.PointingHandCursor
|
||||
hoverEnabled: !loading
|
||||
enabled: !loading
|
||||
|
||||
hoverEnabled: true
|
||||
enabled: !loading && statusBaseButton.enabled
|
||||
|
||||
Loader {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
active: loading
|
||||
sourceComponent: StatusLoadingIndicator {
|
||||
color: d.textColor
|
||||
color: statusBaseButton.enabled ? textColor
|
||||
: disabledTextColor
|
||||
} // Indicator
|
||||
} // Loader
|
||||
|
||||
@@ -129,26 +127,20 @@ Rectangle {
|
||||
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
|
||||
color: statusBaseButton.enabled ? textColor
|
||||
: disabledTextColor
|
||||
} // 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
|
||||
color: statusBaseButton.enabled ? textColor
|
||||
: disabledTextColor
|
||||
} // Text
|
||||
} // Ro
|
||||
|
||||
|
||||
@@ -128,11 +128,6 @@ Item {
|
||||
This property holds a reference to the TextEdit component's horizontalAlignment property.
|
||||
*/
|
||||
property alias horizontalAlignment: edit.horizontalAlignment
|
||||
/*!
|
||||
\qmlproperty alias StatusBaseInput::placeholder
|
||||
This property holds a reference to the placeholder component.
|
||||
*/
|
||||
property alias placeholder: placeholder
|
||||
/*!
|
||||
\qmlproperty alias StatusBaseInput::placeholderText
|
||||
This property holds a reference to the placeholder component's placeholderText property.
|
||||
@@ -313,9 +308,8 @@ Item {
|
||||
|
||||
MouseArea {
|
||||
id: sensor
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
enabled: edit.enabled
|
||||
hoverEnabled: enabled
|
||||
cursorShape: Qt.IBeamCursor
|
||||
onClicked: {
|
||||
if (edit.activeFocus)
|
||||
|
||||
@@ -10,24 +10,21 @@ Column {
|
||||
|
||||
property alias titleText: title.text
|
||||
property alias title: title
|
||||
property alias columns: grid.columns
|
||||
|
||||
property int selectedColorIndex: 0
|
||||
property string selectedColor: ""
|
||||
property var model:[ StatusColors.colors['black'],
|
||||
StatusColors.colors['grey'],
|
||||
StatusColors.colors['blue2'],
|
||||
StatusColors.colors['purple'],
|
||||
StatusColors.colors['cyan'],
|
||||
StatusColors.colors['violet'],
|
||||
StatusColors.colors['red2'],
|
||||
StatusColors.colors['yellow'],
|
||||
StatusColors.colors['green2'],
|
||||
StatusColors.colors['moss'],
|
||||
StatusColors.colors['brown'],
|
||||
StatusColors.colors['brown2'] ]
|
||||
|
||||
signal colorSelected(color color)
|
||||
property var model: [StatusColors.colors['black'],
|
||||
StatusColors.colors['grey'],
|
||||
StatusColors.colors['blue2'],
|
||||
StatusColors.colors['purple'],
|
||||
StatusColors.colors['cyan'],
|
||||
StatusColors.colors['violet'],
|
||||
StatusColors.colors['red2'],
|
||||
StatusColors.colors['yellow'],
|
||||
StatusColors.colors['green2'],
|
||||
StatusColors.colors['moss'],
|
||||
StatusColors.colors['brown'],
|
||||
StatusColors.colors['brown2']]
|
||||
|
||||
spacing: 16
|
||||
|
||||
@@ -39,7 +36,6 @@ Column {
|
||||
}
|
||||
|
||||
Grid {
|
||||
id: grid
|
||||
columns: 6
|
||||
rowSpacing: 16
|
||||
columnSpacing: 32
|
||||
@@ -49,10 +45,9 @@ Column {
|
||||
checked: index === selectedColorIndex
|
||||
radioButtonColor: root.model[index] || "transparent"
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
selectedColorIndex = index;
|
||||
selectedColor = root.model[index];
|
||||
root.colorSelected(selectedColor);
|
||||
if(checked) {
|
||||
selectedColorIndex = index
|
||||
selectedColor = root.model[index]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core.Utils 0.1
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property string emoji
|
||||
property string name
|
||||
property bool removable: false
|
||||
|
||||
signal clicked()
|
||||
|
||||
implicitHeight: 32
|
||||
implicitWidth: row.width + 20
|
||||
radius: height / 2
|
||||
border.color: Theme.palette.baseColor2
|
||||
border.width: 1
|
||||
color: mouseArea.containsMouse ? Theme.palette.primaryColor2 : "transparent"
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: root.clicked()
|
||||
}
|
||||
|
||||
Row {
|
||||
id: row
|
||||
anchors.centerIn: parent
|
||||
|
||||
StatusEmoji {
|
||||
emojiId: root.emoji != "" ? Emoji.iconHex(root.emoji) : ""
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 5
|
||||
height: width
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 13
|
||||
color: root.enabled ? Theme.palette.primaryColor1 : Theme.palette.baseColor1
|
||||
text: root.name
|
||||
}
|
||||
|
||||
StatusIcon {
|
||||
visible: removable
|
||||
color: root.enabled ? Theme.palette.primaryColor1 : Theme.palette.baseColor1
|
||||
icon: "close"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,6 +172,6 @@ Rectangle {
|
||||
|
||||
StatusToolTip {
|
||||
id: statusToolTip
|
||||
visible: !!text && statusFlatRoundButton.hovered
|
||||
visible: !!text && parent.hovered
|
||||
} // Tooltip
|
||||
} // Rectangle
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusModalFloatingButtonsSelector
|
||||
\inherits Row
|
||||
\inqmlmodule StatusQ.Controls
|
||||
\since StatusQ.Controls 0.1
|
||||
\brief The StatusModalFloatingButtonsSelector provides a template for creating a selectable buttons list
|
||||
this list can be parially hidden and the rest of the items are shown under the more button in a popup
|
||||
|
||||
Example of how to use it:
|
||||
|
||||
\qml
|
||||
StatusModalFloatingButtonsSelector {
|
||||
id: floatingHeader
|
||||
model: dummyAccountsModel
|
||||
delegate: StatusAccountSelectorTag {
|
||||
title: "name"
|
||||
icon.name: "iconName"
|
||||
isSelected: floatingHeader.currentIndex === index
|
||||
visible: visibleIndices.includes(index)
|
||||
onClicked: floatingHeader.currentIndex = index
|
||||
}
|
||||
popupMenuDelegate: StatusListItem {
|
||||
implicitWidth: 272
|
||||
title: "name"
|
||||
onClicked: floatingHeader.itemSelected(index)
|
||||
visible: !visibleIndices.includes(index)
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
Row {
|
||||
id: floatingButtons
|
||||
|
||||
/*!
|
||||
\qmlproperty delegate
|
||||
This property represents the delegate of selectable items shown to the user.
|
||||
Can be used to assign delegate to the buttons selector
|
||||
\endqml
|
||||
*/
|
||||
property alias delegate: itemSelectionRepeater.delegate
|
||||
/*!
|
||||
\qmlproperty popupMenuDelegate
|
||||
This property represents the delegate of popupmenu fropm which items can be selected by the user.
|
||||
Can be used to assign delegate to the popupmenu
|
||||
\endqml
|
||||
*/
|
||||
property alias popupMenuDelegate: popupMenuSelectionRepeater.delegate
|
||||
|
||||
/*!
|
||||
\qmlproperty model
|
||||
This property represents the model of selectable items shown to the user.
|
||||
Can be used to assign selectable items in the buttons selector
|
||||
\endqml
|
||||
*/
|
||||
property var model
|
||||
/*!
|
||||
\qmlproperty visibleIndices
|
||||
This property represents the indices from the selectable items that will visible to the user
|
||||
Can be used to set visible items in the buttons selector
|
||||
\endqml
|
||||
*/
|
||||
property var visibleIndices: [0,1,2]
|
||||
/*!
|
||||
\qmlproperty currentIndex
|
||||
This property represents the index of the currently selected item
|
||||
Can be used to set the currnetly selected item in the buttons selector
|
||||
\endqml
|
||||
*/
|
||||
property int currentIndex: 0
|
||||
|
||||
function itemSelected(index) {
|
||||
visibleIndices = [0,1,index]
|
||||
floatingButtons.currentIndex = index
|
||||
popupMenu.close()
|
||||
}
|
||||
|
||||
height: 32
|
||||
spacing: 12
|
||||
clip: true
|
||||
|
||||
Repeater {
|
||||
id: itemSelectionRepeater
|
||||
model: floatingButtons.model
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: button.width
|
||||
height: button.height
|
||||
radius: 8
|
||||
visible: floatingButtons.model.count > 3
|
||||
StatusButton {
|
||||
id: button
|
||||
implicitHeight: 32
|
||||
topPadding: 8
|
||||
bottomPadding: 0
|
||||
defaultLeftPadding: 4
|
||||
defaultRightPadding: 4
|
||||
normalColor: "transparent"
|
||||
icon.name: "more"
|
||||
icon.background.color: "transparent"
|
||||
onClicked: popupMenu.popup(parent.x, y + height + 8)
|
||||
}
|
||||
}
|
||||
|
||||
// Empty item to fill up empty space
|
||||
Item {
|
||||
Layout.preferredHeight: parent.height
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusPopupMenu {
|
||||
id: popupMenu
|
||||
width: layout.width
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
Repeater {
|
||||
id: popupMenuSelectionRepeater
|
||||
model: floatingButtons.model
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,12 @@ Item {
|
||||
e.g. to set the crop window to show and match image's AR use Qt.rect(0, 0, sourceSize.width, sourceSize.height)
|
||||
*/
|
||||
readonly property rect cropRect: d.cropRect
|
||||
/*!
|
||||
\qmlproperty rect StatusImageCrop::cropRect
|
||||
|
||||
The position and zis of the crop rectangle in item's space; without extra spacing
|
||||
*/
|
||||
readonly property alias cropWindow: d.cropWindow
|
||||
/*!
|
||||
\qmlproperty real StatusImageCrop::aspectRatio
|
||||
*/
|
||||
@@ -140,7 +146,7 @@ Item {
|
||||
|
||||
\sa StatusImageCrop::source
|
||||
*/
|
||||
readonly property alias sourceSize: mainImage.sourceSize
|
||||
readonly property size sourceSize: mainImage.sourceSize
|
||||
/*!
|
||||
\qmlproperty real StatusImageCrop::scrToImgScale
|
||||
|
||||
@@ -212,7 +218,7 @@ Item {
|
||||
|
||||
function getZoomRect(scale /*real*/) {
|
||||
const oldCenter = root.rectCenter(root.cropRect)
|
||||
const inflatedRect = root.inflateRectBy(d.minimumCropRect(), 1/scale)
|
||||
const inflatedRect = root.inflateRectBy(root.minimumCropRect(), 1/scale)
|
||||
return root.recenterRect(inflatedRect, oldCenter);
|
||||
}
|
||||
|
||||
@@ -242,34 +248,44 @@ Item {
|
||||
return Qt.rect(newCenter.x - target.width/2 , newCenter.y - target.height/2, target.width, target.height)
|
||||
}
|
||||
|
||||
function fillContentInWindow(contentSize /*size*/, windowSize /*size*/) {
|
||||
const contentAR = contentSize.width/contentSize.height
|
||||
const windowAR = windowSize.width/windowSize.height
|
||||
const heightBound = contentAR > windowAR
|
||||
if(heightBound) {
|
||||
const wWidth = contentSize.height * windowAR
|
||||
const horizontalBorder = (contentSize.width - wWidth)/2
|
||||
return Qt.rect(horizontalBorder, 0, wWidth, contentSize.height)
|
||||
}
|
||||
else {
|
||||
const wHeight = contentSize.width / windowAR
|
||||
const verticalBorder = (contentSize.height - wHeight)/2
|
||||
return Qt.rect(0, verticalBorder, contentSize.width, wHeight)
|
||||
}
|
||||
//> cropRect for minimum zoom: 1.0
|
||||
function minimumCropRect() {
|
||||
const sourceAR = root.sourceSize.width/root.sourceSize.height
|
||||
const widthBound = sourceAR > root.aspectRatio
|
||||
const minCropSize = widthBound ? Qt.size(root.sourceSize.width, root.sourceSize.width/root.aspectRatio)
|
||||
: Qt.size(root.sourceSize.height * root.aspectRatio, root.sourceSize.height)
|
||||
let res = Qt.rect(widthBound ? 0 : -(root.sourceSize.width - minCropSize.width)/2, // x
|
||||
widthBound ? -(root.sourceSize.height - minCropSize.height)/2 : 0, // y
|
||||
minCropSize.width, minCropSize.height)
|
||||
return res
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
property rect cropRect
|
||||
property rect cropRect: fillContentInSquaredWindow(root.sourceSize)
|
||||
onCropRectChanged: windowRect.requestPaint()
|
||||
|
||||
readonly property real zoomToFill: {
|
||||
const rectangle = root.fillContentInWindow(root.sourceSize, d.cropWindowSize)
|
||||
const rectangle = fillContentInSquaredWindow(root.sourceSize)
|
||||
return d.currentZoom(root.sourceSize, Qt.size(rectangle.width, rectangle.height))
|
||||
}
|
||||
|
||||
property size cropWindowSize: Qt.size(d.cropRect.width, d.cropRect.height)
|
||||
property rect cropWindow
|
||||
// Probably called from render thread, run async
|
||||
signal updateCropWindow(rect newRect)
|
||||
onUpdateCropWindow: cropWindow = newRect
|
||||
|
||||
function fillContentInSquaredWindow(c /*size*/) {
|
||||
if(c.width > c.height) {
|
||||
const border = (c.width - c.height)/2
|
||||
return Qt.rect(border, 0, c.height, c.height)
|
||||
}
|
||||
else {
|
||||
const border = (c.height - c.width)/2
|
||||
return Qt.rect(0, border, c.width, c.width)
|
||||
}
|
||||
}
|
||||
|
||||
//> 1.0 is the content represented by w fully inscribed in c
|
||||
function currentZoom(c /*size*/, w /*size*/) {
|
||||
@@ -277,26 +293,10 @@ Item {
|
||||
const hScale = c.height/w.height
|
||||
return Math.max(wScale, hScale)
|
||||
}
|
||||
|
||||
//> cropRect for minimum zoom: 1.0
|
||||
function minimumCropRect() {
|
||||
const sourceAR = root.sourceSize.width/root.sourceSize.height
|
||||
const widthBound = sourceAR > root.aspectRatio
|
||||
const minCropSize = widthBound ? Qt.size(root.sourceSize.width, root.sourceSize.width/root.aspectRatio)
|
||||
: Qt.size(root.sourceSize.height * root.aspectRatio, root.sourceSize.height)
|
||||
let res = Qt.rect(widthBound ? 0 : -(root.sourceSize.width - minCropSize.width)/2, // x
|
||||
widthBound ? -(root.sourceSize.height - minCropSize.height)/2 : 0, // y
|
||||
minCropSize.width, minCropSize.height)
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
onWindowStyleChanged: windowRect.requestPaint()
|
||||
onRadiusChanged: windowRect.requestPaint()
|
||||
onSourceSizeChanged: {
|
||||
if(d.cropWindowSize.width > 0 && d.cropWindowSize.height > 0)
|
||||
d.cropRect = root.fillContentInWindow(sourceSize, d.cropWindowSize)
|
||||
}
|
||||
onSourceSizeChanged: d.cropRect = d.fillContentInSquaredWindow(sourceSize)
|
||||
|
||||
Canvas {
|
||||
id: windowRect
|
||||
@@ -330,6 +330,7 @@ Item {
|
||||
ctx.roundedRect(cW.x, cW.y, cW.width, cW.height, root.radius, root.radius)
|
||||
ctx.fill()
|
||||
ctx.restore()
|
||||
d.updateCropWindow(cW)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Backpressure 1.0
|
||||
@@ -30,7 +29,23 @@ import StatusQ.Controls.Validators 0.1
|
||||
*/
|
||||
Item {
|
||||
id: root
|
||||
implicitWidth: 480
|
||||
implicitHeight: (label.visible ?
|
||||
label.anchors.topMargin +
|
||||
label.height :
|
||||
charLimitLabel.visible ?
|
||||
charLimitLabel.anchors.topMargin +
|
||||
charLimitLabel.height :
|
||||
0) +
|
||||
statusBaseInput.anchors.topMargin +
|
||||
statusBaseInput.height +
|
||||
(errorMessage.visible ?
|
||||
errorMessage.anchors.topMargin +
|
||||
errorMessage.height :
|
||||
0) + 8
|
||||
|
||||
height: implicitHeight
|
||||
width: implicitWidth
|
||||
/*!
|
||||
\qmlproperty alias StatusInput::input
|
||||
This property holds a reference to the TextEdit component.
|
||||
@@ -305,83 +320,92 @@ Item {
|
||||
root.valid = Object.values(asyncErrors).length == 0
|
||||
}
|
||||
|
||||
implicitWidth: inputLayout.implicitWidth
|
||||
implicitHeight: inputLayout.implicitHeight
|
||||
height: implicitHeight
|
||||
width: implicitWidth
|
||||
|
||||
Component.onCompleted: validate()
|
||||
|
||||
ColumnLayout {
|
||||
id: inputLayout
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
StatusBaseText {
|
||||
id: label
|
||||
visible: !!root.label
|
||||
elide: Text.ElideRight
|
||||
text: root.label
|
||||
font.pixelSize: 15
|
||||
color: statusBaseInput.enabled ? Theme.palette.directColor1 : Theme.palette.baseColor1
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: secondaryLabel
|
||||
visible: !!root.secondaryLabel
|
||||
elide: Text.ElideRight
|
||||
text: root.secondaryLabel
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: charLimitLabel
|
||||
|
||||
visible: root.charLimit > 0
|
||||
|
||||
text: "%1 / %2".arg(statusBaseInput.text.length).arg(root.charLimit)
|
||||
font.pixelSize: 12
|
||||
color: statusBaseInput.enabled ? Theme.palette.baseColor1 : Theme.palette.directColor6
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseInput {
|
||||
id: statusBaseInput
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
maximumLength: root.charLimit
|
||||
onTextChanged: root.validate()
|
||||
|
||||
Keys.forwardTo: [root]
|
||||
onIconClicked: root.iconClicked()
|
||||
onKeyPressed: {
|
||||
root.keyPressed(event);
|
||||
}
|
||||
onEditChanged: {
|
||||
root.editClicked();
|
||||
}
|
||||
Row {
|
||||
id: labelRow
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.topMargin: visible ? 8 : 0
|
||||
anchors.leftMargin: root.leftPadding
|
||||
anchors.right: (charLimitLabel.visible ? charLimitLabel.right : parent.right)
|
||||
anchors.rightMargin: root.rightPadding
|
||||
height: visible ? 17 : 0
|
||||
visible: !!root.label
|
||||
spacing: 5
|
||||
StatusBaseText {
|
||||
id: label
|
||||
elide: Text.ElideRight
|
||||
text: root.label
|
||||
font.pixelSize: 15
|
||||
color: statusBaseInput.enabled ? Theme.palette.directColor1 : Theme.palette.baseColor1
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: errorMessage
|
||||
|
||||
visible: !!text && !statusBaseInput.valid
|
||||
|
||||
font.pixelSize: 12
|
||||
color: Theme.palette.dangerColor1
|
||||
|
||||
horizontalAlignment: Text.AlignRight
|
||||
wrapMode: Text.WordWrap
|
||||
id: secondaryLabel
|
||||
height: visible ? 17 : 0
|
||||
visible: !!root.secondaryLabel
|
||||
elide: Text.ElideRight
|
||||
text: root.secondaryLabel
|
||||
font.pixelSize: 15
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: charLimitLabel
|
||||
height: visible ? implicitHeight : 0
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: visible ? 11 : 0
|
||||
anchors.rightMargin: root.rightPadding
|
||||
visible: root.charLimit > 0
|
||||
|
||||
text: "%1 / %2".arg(statusBaseInput.text.length).arg(root.charLimit)
|
||||
font.pixelSize: 12
|
||||
color: statusBaseInput.enabled ? Theme.palette.baseColor1 : Theme.palette.directColor6
|
||||
}
|
||||
|
||||
StatusBaseInput {
|
||||
id: statusBaseInput
|
||||
anchors.top: labelRow.visible ? labelRow.bottom :
|
||||
charLimitLabel.visible ? charLimitLabel.bottom : parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: charLimitLabel.visible ? 11 : 8
|
||||
anchors.leftMargin: root.leftPadding
|
||||
anchors.rightMargin: root.rightPadding
|
||||
maximumLength: root.charLimit
|
||||
onTextChanged: root.validate()
|
||||
|
||||
Keys.forwardTo: [root]
|
||||
onIconClicked: root.iconClicked()
|
||||
onKeyPressed: {
|
||||
root.keyPressed(event);
|
||||
}
|
||||
onEditChanged: {
|
||||
root.editClicked();
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: errorMessage
|
||||
|
||||
anchors.top: statusBaseInput.bottom
|
||||
anchors.topMargin: 11
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: root.rightPadding
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: root.leftPadding
|
||||
|
||||
height: visible ? implicitHeight : 0
|
||||
visible: !!text && !statusBaseInput.valid
|
||||
|
||||
font.pixelSize: 12
|
||||
color: Theme.palette.dangerColor1
|
||||
|
||||
|
||||
horizontalAlignment: Text.AlignRight
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +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
|
||||
|
||||
StatusSlider {
|
||||
id: root
|
||||
|
||||
property var model: []
|
||||
property int fontSize: 12
|
||||
property int labelMargin: 2
|
||||
|
||||
fillColor: bgColor
|
||||
handleColor: Theme.palette.primaryColor1
|
||||
handleSize: 14
|
||||
from: 0
|
||||
to: model.length - 1
|
||||
stepSize: 1
|
||||
snapMode: Slider.SnapAlways
|
||||
|
||||
decoration: Item {
|
||||
implicitHeight: handleSize + fontSize + labelMargin
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: root.model
|
||||
|
||||
Rectangle {
|
||||
x: (background.width - width * 0.5) / (repeater.count - 1) * index
|
||||
y: (root.bgHeight -height) / 2
|
||||
implicitWidth: root.handleSize
|
||||
implicitHeight: root.handleSize
|
||||
radius: root.handleSize / 2
|
||||
color: root.bgColor
|
||||
border.color: Theme.palette.statusAppLayout.backgroundColor
|
||||
border.width: 2
|
||||
|
||||
StatusBaseText {
|
||||
anchors.top: parent.bottom
|
||||
anchors.topMargin: root.labelMargin
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
color: Theme.palette.baseColor1
|
||||
font.pixelSize: root.fontSize
|
||||
text: modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,9 +211,8 @@ Item {
|
||||
SequentialAnimation {
|
||||
id: blinkingAnimation
|
||||
loops: Animation.Infinite
|
||||
running: visible
|
||||
NumberAnimation { target: inner; property: "opacity"; to: 0; duration: 800; running: visible }
|
||||
NumberAnimation { target: inner; property: "opacity"; to: 1; duration: 800; running: visible }
|
||||
NumberAnimation { target: inner; property: "opacity"; to: 0; duration: 800 }
|
||||
NumberAnimation { target: inner; property: "opacity"; to: 1; duration: 800 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,27 +12,14 @@ Rectangle {
|
||||
height: 23
|
||||
rotation: 0
|
||||
|
||||
property color hoverColor: {
|
||||
switch(statusRoundButton.type) {
|
||||
case StatusRoundButton.Type.Primary:
|
||||
return Theme.palette.primaryColor1;
|
||||
case StatusRoundButton.Type.Secondary:
|
||||
return Theme.palette.indirectColor1;
|
||||
case StatusRoundButton.Type.Tertiary:
|
||||
return Theme.palette.primaryColor1;
|
||||
}
|
||||
}
|
||||
|
||||
color: {
|
||||
switch(statusRoundButton.type) {
|
||||
case StatusRoundButton.Type.Primary:
|
||||
return Theme.palette.primaryColor1;
|
||||
case StatusRoundButton.Type.Secondary:
|
||||
return Theme.palette.indirectColor1;
|
||||
case StatusRoundButton.Type.Tertiary:
|
||||
return Theme.palette.baseColor1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disabledColor: {
|
||||
switch(statusRoundButton.type) {
|
||||
@@ -40,8 +27,6 @@ Rectangle {
|
||||
return Theme.palette.baseColor1;
|
||||
case StatusRoundButton.Type.Secondary:
|
||||
return Theme.palette.indirectColor1;
|
||||
case StatusRoundButton.Type.Tertiary:
|
||||
return Theme.palette.baseColor1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,9 +46,11 @@ Rectangle {
|
||||
|
||||
enum Type {
|
||||
Primary,
|
||||
Secondary,
|
||||
Tertiary
|
||||
Secondary
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Implementation
|
||||
|
||||
QtObject {
|
||||
@@ -75,8 +62,6 @@ Rectangle {
|
||||
return Theme.palette.primaryColor3;
|
||||
case StatusRoundButton.Type.Secondary:
|
||||
return Theme.palette.primaryColor1;
|
||||
case StatusRoundButton.Type.Tertiary:
|
||||
return "transparent";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,8 +71,6 @@ Rectangle {
|
||||
return Theme.palette.primaryColor2;
|
||||
case StatusRoundButton.Type.Secondary:
|
||||
return Theme.palette.miscColor1;
|
||||
case StatusRoundButton.Type.Tertiary:
|
||||
return Theme.palette.primaryColor3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,39 +80,31 @@ Rectangle {
|
||||
return Theme.palette.baseColor2;
|
||||
case StatusRoundButton.Type.Secondary:
|
||||
return Theme.palette.baseColor1;
|
||||
case StatusRoundButton.Type.Tertiary:
|
||||
return "transparent";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
readonly property color iconColor: !statusRoundButton.enabled ? statusRoundButton.icon.disabledColor :
|
||||
(statusRoundButton.enabled && statusRoundButton.hovered) ? statusRoundButton.icon.hoverColor :
|
||||
statusRoundButton.icon.color
|
||||
}
|
||||
|
||||
implicitWidth: 44
|
||||
implicitHeight: 44
|
||||
radius: width / 2;
|
||||
|
||||
color: {
|
||||
if (statusRoundButton.enabled)
|
||||
if (statusRoundButton.enabled) {
|
||||
return sensor.containsMouse || highlighted ? backgroundSettings.hoverColor
|
||||
: backgroundSettings.color;
|
||||
return backgroundSettings.disabledColor
|
||||
: backgroundSettings.color
|
||||
} else {
|
||||
return backgroundSettings.disabledColor
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: sensor
|
||||
|
||||
anchors.fill: parent
|
||||
cursorShape: loading ? Qt.ArrowCursor
|
||||
: Qt.PointingHandCursor
|
||||
hoverEnabled: !loading
|
||||
enabled: !loading
|
||||
|
||||
hoverEnabled: true
|
||||
enabled: !loading && statusRoundButton.enabled
|
||||
|
||||
StatusIcon {
|
||||
id: statusIcon
|
||||
@@ -142,13 +117,25 @@ Rectangle {
|
||||
width: statusRoundButton.icon.width
|
||||
height: statusRoundButton.icon.height
|
||||
|
||||
color: d.iconColor
|
||||
color: {
|
||||
if (statusRoundButton.enabled) {
|
||||
return statusRoundButton.icon.color
|
||||
} else {
|
||||
return statusRoundButton.icon.disabledColor
|
||||
}
|
||||
}
|
||||
} // Icon
|
||||
Loader {
|
||||
active: loading
|
||||
anchors.centerIn: parent
|
||||
sourceComponent: StatusLoadingIndicator {
|
||||
color: d.iconColor
|
||||
color: {
|
||||
if (statusRoundButton.enabled) {
|
||||
return statusRoundButton.icon.color
|
||||
} else {
|
||||
return statusRoundButton.icon.disabledColor
|
||||
}
|
||||
}
|
||||
} // Indicator
|
||||
} // Loader
|
||||
|
||||
|
||||
@@ -114,6 +114,11 @@ Item {
|
||||
|
||||
id: seedWordInput
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: parent.height
|
||||
input.anchors.topMargin: 0
|
||||
input.anchors.leftMargin: 0
|
||||
input.anchors.rightMargin: 0
|
||||
input.anchors.bottom: input.parent.bottom
|
||||
input.leftComponent: StatusBaseText {
|
||||
text: root.leftComponentText
|
||||
color: seedWordInput.input.edit.activeFocus ?
|
||||
|
||||
@@ -11,55 +11,40 @@ import StatusQ.Controls 0.1
|
||||
as the /c handle so user can grab it fully.
|
||||
*/
|
||||
Slider {
|
||||
id: root
|
||||
|
||||
property int handleSize: 28
|
||||
property int bgHeight: 4
|
||||
property color handleColor: Theme.palette.white
|
||||
property color bgColor: Theme.palette.baseColor2
|
||||
property color fillColor: Theme.palette.primaryColor1
|
||||
|
||||
property alias decoration: decorationContainer.sourceComponent
|
||||
id: statusSlider
|
||||
|
||||
implicitWidth: 360
|
||||
implicitHeight: Math.max(handle.implicitHeight,
|
||||
background.implicitHeight + decorationContainer.height)
|
||||
implicitHeight: Math.max(handle.implicitHeight, background.implicitHeight)
|
||||
|
||||
leftPadding: 0
|
||||
|
||||
background: Rectangle {
|
||||
id: bgRect
|
||||
|
||||
x: root.leftPadding
|
||||
y: root.topPadding
|
||||
x: statusSlider.leftPadding
|
||||
y: statusSlider.topPadding + statusSlider.availableHeight / 2 - height / 2
|
||||
implicitWidth: 100
|
||||
implicitHeight: bgHeight
|
||||
width: root.availableWidth
|
||||
implicitHeight: 4
|
||||
width: statusSlider.availableWidth
|
||||
height: implicitHeight
|
||||
color: root.bgColor
|
||||
color: Theme.palette.primaryColor3
|
||||
radius: 2
|
||||
|
||||
Loader {
|
||||
id: decorationContainer
|
||||
anchors.top: parent.top
|
||||
width: parent.height
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: root.visualPosition * parent.width
|
||||
width: statusSlider.visualPosition * parent.width
|
||||
height: parent.height
|
||||
color: root.fillColor
|
||||
color: Theme.palette.primaryColor1
|
||||
radius: 2
|
||||
}
|
||||
} // background
|
||||
|
||||
handle: Rectangle {
|
||||
x: root.leftPadding + root.visualPosition * (root.availableWidth - width / 2)
|
||||
x: statusSlider.leftPadding + statusSlider.visualPosition * (statusSlider.availableWidth - width / 2)
|
||||
anchors.verticalCenter: bgRect.verticalCenter
|
||||
color: root.handleColor
|
||||
implicitWidth: root.handleSize
|
||||
implicitHeight: root.handleSize
|
||||
radius: root.handleSize / 2
|
||||
color: Theme.palette.white
|
||||
implicitWidth: 28
|
||||
implicitHeight: 28
|
||||
radius: 14
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
width: parent.width
|
||||
|
||||
@@ -52,7 +52,7 @@ Switch {
|
||||
|
||||
transitions: Transition {
|
||||
reversible: true
|
||||
NumberAnimation { properties: "x"; easing.type: Easing.Linear; duration: 120 }
|
||||
NumberAnimation { properties: "x"; easing.type: Easing.Linear; duration: 120; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ TabButton {
|
||||
Rectangle {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
visible: root.enabled && (root.checked || root.hovered)
|
||||
visible: root.checked || root.hovered
|
||||
implicitWidth: 24
|
||||
implicitHeight: 2
|
||||
radius: 4
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
/*!
|
||||
\qmltype StatusTagItem
|
||||
\inherits Item
|
||||
\inqmlmodule StatusQ.Controls
|
||||
\since StatusQ.Controls 0.1
|
||||
\brief Reprsents a tag item.
|
||||
Inherits \l{https://doc.qt.io/qt-5/qml-qtquick-rectangle.html}{Item}.
|
||||
|
||||
The \c StatusTagItem represents a tag item where a name and icon can be displayed and can be clicked.
|
||||
Example:
|
||||
|
||||
\qml
|
||||
StatusTagItem {
|
||||
isReadonly: model.isReadonly
|
||||
text: model.name
|
||||
icon: model.tagIcon
|
||||
|
||||
onClicked: { console.log("Tag selected!") }
|
||||
}
|
||||
\endqml
|
||||
|
||||
For a list of components available see StatusQ.
|
||||
*/
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
/*!
|
||||
\qmlproperty bool StatusTagItem::isReadonly
|
||||
This property sets if the tag is readonly or not.
|
||||
*/
|
||||
property bool isReadonly
|
||||
/*!
|
||||
\qmlproperty string StatusTagItem::name
|
||||
This property sets the tag text to display.
|
||||
*/
|
||||
property string text
|
||||
/*!
|
||||
\qmlproperty string StatusTagItem::icon
|
||||
This property sets the tag icon to display.
|
||||
*/
|
||||
property string icon
|
||||
|
||||
/*!
|
||||
\qmlsignal
|
||||
This signal is emitted when the tag is clicked.
|
||||
*/
|
||||
signal clicked()
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
property int tagMargins: 8
|
||||
property int tagIconsSize: 20
|
||||
|
||||
function getTagColor(isReadonly) {
|
||||
if(isReadonly) {
|
||||
return Theme.palette.baseColor1
|
||||
}
|
||||
else {
|
||||
return mouseArea.containsMouse ? Theme.palette.miscColor1 : Theme.palette.primaryColor1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
width: tagRow.implicitWidth + 2 * d.tagMargins
|
||||
height: 30
|
||||
color: d.getTagColor(root.isReadonly)
|
||||
radius: 8
|
||||
Row {
|
||||
id: tagRow
|
||||
height: parent.height
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: d.tagMargins
|
||||
anchors.rightMargin: d.tagMargins
|
||||
spacing: 2
|
||||
|
||||
StatusIcon {
|
||||
visible: root.icon
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Theme.palette.indirectColor1
|
||||
width: root.icon ? d.tagIconsSize : 0
|
||||
height: d.tagIconsSize
|
||||
icon: root.icon
|
||||
}
|
||||
StatusBaseText {
|
||||
id: nameText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Theme.palette.indirectColor1
|
||||
font.pixelSize: 15
|
||||
text: root.text
|
||||
}
|
||||
StatusIcon {
|
||||
id: closeIcon
|
||||
visible: !root.isReadonly
|
||||
anchors.leftMargin: d.tagMargins
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Theme.palette.indirectColor1
|
||||
width: d.tagIconsSize
|
||||
height: d.tagIconsSize
|
||||
icon: "close"
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
enabled: !root.isReadonly
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: { root.clicked() }
|
||||
}
|
||||
}
|
||||
@@ -108,7 +108,6 @@ RowLayout {
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
running: visible
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +155,7 @@ RowLayout {
|
||||
from: 0
|
||||
to: parent.width
|
||||
duration: 800
|
||||
running: visible && mouseArea.containsPress
|
||||
running: mouseArea.containsPress
|
||||
|
||||
onStopped: {
|
||||
if (pressIndicator.width == parent.width) {
|
||||
|
||||
@@ -18,12 +18,10 @@ StatusButton 0.1 StatusButton.qml
|
||||
StatusFlatButton 0.1 StatusFlatButton.qml
|
||||
StatusRoundButton 0.1 StatusRoundButton.qml
|
||||
StatusFlatRoundButton 0.1 StatusFlatRoundButton.qml
|
||||
StatusCommunityTag 0.1 StatusCommunityTag.qml
|
||||
StatusSwitch 0.1 StatusSwitch.qml
|
||||
StatusRadioButton 0.1 StatusRadioButton.qml
|
||||
StatusCheckBox 0.1 StatusCheckBox.qml
|
||||
StatusSlider 0.1 StatusSlider.qml
|
||||
StatusLabeledSlider 0.1 StatusLabeledSlider.qml
|
||||
StatusSelect 0.1 StatusSelect.qml
|
||||
StatusBaseInput 0.1 StatusBaseInput.qml
|
||||
StatusInput 0.1 StatusInput.qml
|
||||
@@ -36,12 +34,9 @@ StatusSwitchTabBar 0.1 StatusSwitchTabBar.qml
|
||||
StatusSelectableText 0.1 StatusSelectableText.qml
|
||||
StatusTabBar 0.1 StatusTabBar.qml
|
||||
StatusTabButton 0.1 StatusTabButton.qml
|
||||
StatusTagItem 0.1 StatusTagItem.qml
|
||||
StatusTokenInlineSelector 0.1 StatusTokenInlineSelector.qml
|
||||
StatusWalletColorButton 0.1 StatusWalletColorButton.qml
|
||||
StatusWalletColorSelect 0.1 StatusWalletColorSelect.qml
|
||||
StatusColorSelectorGrid 0.1 StatusColorSelectorGrid.qml
|
||||
StatusSeedPhraseInput 0.1 StatusSeedPhraseInput.qml
|
||||
StatusImageCrop 0.1 StatusImageCrop.qml
|
||||
StatusFloatingButtonsSelector 0.1 StatusFloatingButtonsSelector.qml
|
||||
StatusActivityCenterButton 0.1 StatusActivityCenterButton.qml
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
StackLayout {
|
||||
id: root
|
||||
|
||||
property int previousIndex: 0
|
||||
property int duration: 300
|
||||
|
||||
property var items: children
|
||||
|
||||
readonly property var previousItem: items[previousIndex]
|
||||
readonly property var currentItem: items[currentIndex]
|
||||
|
||||
clip: true
|
||||
|
||||
Component.onCompleted: {
|
||||
previousIndex = currentIndex
|
||||
|
||||
for(var i = 1; i < count; ++i) {
|
||||
children[i].opacity = 0
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: crossFader
|
||||
|
||||
ParallelAnimation {
|
||||
property Item fadeOutTarget
|
||||
property Item fadeInTarget
|
||||
readonly property bool direct: previousIndex < currentIndex
|
||||
|
||||
NumberAnimation {
|
||||
target: fadeOutTarget
|
||||
property: "opacity"
|
||||
to: 0
|
||||
duration: root.duration
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
target: fadeInTarget
|
||||
property: "opacity"
|
||||
to: 1
|
||||
duration: root.duration
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
target: fadeOutTarget
|
||||
property: "x"
|
||||
from: 0
|
||||
to: direct ? -root.width : root.width
|
||||
duration: root.duration
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
target: fadeInTarget
|
||||
property: "x"
|
||||
from: direct ? root.width : -root.width
|
||||
to: 0
|
||||
duration: root.duration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
items = root.children;
|
||||
|
||||
if (previousItem && currentItem && (previousItem != currentItem)) {
|
||||
previousItem.visible = true;
|
||||
currentItem.visible = true;
|
||||
var crossFaderAnim = crossFader.createObject(parent,
|
||||
{
|
||||
fadeOutTarget: previousItem,
|
||||
fadeInTarget: currentItem
|
||||
});
|
||||
crossFaderAnim.restart();
|
||||
}
|
||||
previousIndex = currentIndex;
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import StatusQ.Core.Theme 0.1
|
||||
width: 240
|
||||
text: qsTr("Hello World!")
|
||||
font.pixelSize: 24
|
||||
color: Theme.palette.directColor1
|
||||
color: Theme.pallete.directColor1
|
||||
}
|
||||
\endqml
|
||||
|
||||
@@ -27,5 +27,4 @@ import StatusQ.Core.Theme 0.1
|
||||
|
||||
Text {
|
||||
font.family: Theme.palette.baseFont.name
|
||||
color: Theme.palette.directColor1
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ QtObject {
|
||||
id: appTheme
|
||||
property QtObject palette: StatusLightTheme {}
|
||||
|
||||
property int bigPadding: 24
|
||||
property int radius: 8
|
||||
|
||||
function setTheme(theme) {
|
||||
palette = theme
|
||||
}
|
||||
|
||||
@@ -48,10 +48,6 @@ QtObject {
|
||||
const match = parsed.match('src=".*\/(.+?).svg');
|
||||
return (match && match.length >= 2) ? match[1] : undefined;
|
||||
}
|
||||
// NOTE: doing the same thing as iconId but without checking Twemoji internal checks
|
||||
function iconHex(text) {
|
||||
return text.codePointAt(0).toString(16);
|
||||
}
|
||||
function fromCodePoint(value) {
|
||||
return Twemoji.twemoji.convert.fromCodePoint(value)
|
||||
}
|
||||
|
||||
@@ -45,17 +45,16 @@ QtObject {
|
||||
return false
|
||||
}
|
||||
|
||||
function findAssetByChainAndSymbol(chainIdToFind, assets, symbolToFind) {
|
||||
function findAssetBySymbol(assets, symbolToFind) {
|
||||
for(var i=0; i<assets.rowCount(); i++) {
|
||||
const symbol = assets.rowData(i, "symbol")
|
||||
if (symbol.toLowerCase() === symbolToFind.toLowerCase() && assets.hasChain(i, parseInt(chainIdToFind))) {
|
||||
if (symbol.toLowerCase() === symbolToFind.toLowerCase()) {
|
||||
return {
|
||||
name: assets.rowData(i, "name"),
|
||||
symbol,
|
||||
totalBalance: assets.rowData(i, "totalBalance"),
|
||||
totalCurrencyBalance: assets.rowData(i, "totalCurrencyBalance"),
|
||||
fiatBalance: assets.rowData(i, "totalCurrencyBalance"),
|
||||
chainId: chainIdToFind,
|
||||
balance: assets.rowData(i, "balance"),
|
||||
address: assets.rowData(i, "address"),
|
||||
currencyBalance: assets.rowData(i, "currencyBalance")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,4 +9,3 @@ StatusImageSettings 0.1 StatusImageSettings.qml
|
||||
StatusModalHeaderSettings 0.1 StatusModalHeaderSettings.qml
|
||||
StatusTooltipSettings 0.1 StatusTooltipSettings.qml
|
||||
StatusAppNavBarFilterModel 0.1 StatusAppNavBarFilterModel.qml
|
||||
StatusAnimatedStack 0.1 StatusAnimatedStack.qml
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtQml.Models 2.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
Dialog {
|
||||
id: root
|
||||
|
||||
anchors.centerIn: Overlay.overlay
|
||||
|
||||
padding: 16
|
||||
margins: 64
|
||||
modal: true
|
||||
|
||||
standardButtons: Dialog.Cancel | Dialog.Ok
|
||||
|
||||
Overlay.modal: Rectangle {
|
||||
color: Theme.palette.backdropColor
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: Theme.palette.statusModal.backgroundColor
|
||||
radius: 8
|
||||
}
|
||||
|
||||
header: StatusDialogHeader {
|
||||
visible: root.title
|
||||
headline.title: root.title
|
||||
actions.closeButton.onClicked: root.close()
|
||||
}
|
||||
|
||||
footer: StatusDialogFooter {
|
||||
id: footerItem
|
||||
|
||||
readonly property int rejectRoleFlags: Dialog.Cancel | Dialog.Close | Dialog.Abort
|
||||
readonly property int noRoleFlags: Dialog.No | Dialog.NoToAll
|
||||
readonly property int acceptRoleFlags: Dialog.Ok | Dialog.Open | Dialog.Save | Dialog.SaveAll | Dialog.Retry | Dialog.Ignore
|
||||
readonly property int yesRoleFlags: Dialog.Yes | Dialog.YesToAll
|
||||
|
||||
visible: rightButtons &&
|
||||
root.standardButtons & (rejectRoleFlags | noRoleFlags | acceptRoleFlags | yesRoleFlags | Dialog.ApplyRole)
|
||||
|
||||
rightButtons: ObjectModel {
|
||||
StatusButton {
|
||||
visible: root.standardButtons & footerItem.rejectRoleFlags
|
||||
type: StatusButton.Danger
|
||||
text: {
|
||||
if (root.standardButtons & Dialog.Close) return qsTr("Close")
|
||||
if (root.standardButtons & Dialog.Abort) return qsTr("Abort")
|
||||
return qsTr("Cancel")
|
||||
}
|
||||
|
||||
onClicked: root.reject()
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
visible: root.standardButtons & footerItem.noRoleFlags
|
||||
type: StatusButton.Danger
|
||||
text: {
|
||||
if (root.standardButtons & Dialog.NoToAll) return qsTr("No to all")
|
||||
return qsTr("No")
|
||||
}
|
||||
|
||||
onClicked: root.reject()
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
visible: root.standardButtons & footerItem.acceptRoleFlags
|
||||
text: {
|
||||
if (root.standardButtons & Dialog.Open) return qsTr("Open")
|
||||
if (root.standardButtons & Dialog.Save) return qsTr("Save")
|
||||
if (root.standardButtons & Dialog.SaveAll) return qsTr("Save all")
|
||||
if (root.standardButtons & Dialog.Retry) return qsTr("Retry")
|
||||
if (root.standardButtons & Dialog.Ignore) return qsTr("Ignore")
|
||||
return qsTr("Ok")
|
||||
}
|
||||
|
||||
onClicked: root.accept()
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
visible: root.standardButtons & footerItem.yesRoleFlags
|
||||
type: StatusButton.Danger
|
||||
text: {
|
||||
if (root.standardButtons & Dialog.YesToAll) return qsTr("Yes to all")
|
||||
return qsTr("Yes")
|
||||
}
|
||||
|
||||
onClicked: root.accept()
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
visible: root.standardButtons & Dialog.ApplyRole
|
||||
text: qsTr("Apply")
|
||||
|
||||
onClicked: root.applied()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
Rectangle {
|
||||
color: Theme.palette.baseColor2
|
||||
implicitHeight: 1
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtQml.Models 2.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property ObjectModel leftButtons
|
||||
property ObjectModel rightButtons
|
||||
|
||||
color: Theme.palette.statusModal.backgroundColor
|
||||
radius: 8
|
||||
|
||||
implicitHeight: layout.implicitHeight + layout.anchors.topMargin + layout.anchors.bottomMargin
|
||||
implicitWidth: layout.implicitWidth + layout.anchors.leftMargin + layout.anchors.rightMargin
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
|
||||
clip: true
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 16
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.leftButtons
|
||||
onItemAdded: item.Layout.fillHeight = true
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.rightButtons
|
||||
onItemAdded: item.Layout.fillHeight = true
|
||||
}
|
||||
}
|
||||
|
||||
StatusDialogDivider {
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
readonly property alias headline: headline
|
||||
readonly property alias actions: actions
|
||||
|
||||
property alias leftComponent: leftComponentLoader.sourceComponent
|
||||
|
||||
color: Theme.palette.statusModal.backgroundColor
|
||||
radius: 8
|
||||
|
||||
implicitHeight: layout.implicitHeight + layout.anchors.topMargin + layout.anchors.bottomMargin
|
||||
implicitWidth: layout.implicitWidth + layout.anchors.leftMargin + layout.anchors.rightMargin
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
|
||||
clip: true
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 16
|
||||
}
|
||||
|
||||
spacing: 8
|
||||
|
||||
Loader {
|
||||
id: leftComponentLoader
|
||||
|
||||
Layout.fillHeight: true
|
||||
visible: sourceComponent
|
||||
}
|
||||
|
||||
StatusTitleSubtitle {
|
||||
id: headline
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
StatusHeaderActions {
|
||||
id: actions
|
||||
|
||||
Layout.alignment: Qt.AlignTop
|
||||
}
|
||||
}
|
||||
|
||||
StatusDialogDivider {
|
||||
anchors.bottom: parent.bottom
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtQml.Models 2.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property ObjectModel customButtons
|
||||
|
||||
readonly property alias closeButton: closeButton
|
||||
readonly property alias infoButton: infoButton
|
||||
|
||||
implicitHeight: layout.implicitHeight
|
||||
implicitWidth: layout.implicitWidth
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
readonly property int buttonSize: 32
|
||||
readonly property int iconSize: 20
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
Repeater {
|
||||
model: root.customButtons
|
||||
onItemAdded: {
|
||||
item.Layout.fillHeight = true
|
||||
item.Layout.preferredHeight = d.buttonSize
|
||||
item.Layout.preferredWidth = d.buttonSize
|
||||
}
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: infoButton
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: d.buttonSize
|
||||
Layout.preferredWidth: d.buttonSize
|
||||
|
||||
visible: false
|
||||
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
icon.name: "info"
|
||||
icon.color: Theme.palette.directColor1
|
||||
icon.width: d.iconSize
|
||||
icon.height: d.iconSize
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: closeButton
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: d.buttonSize
|
||||
Layout.preferredWidth: d.buttonSize
|
||||
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
icon.name: "close"
|
||||
icon.color: Theme.palette.directColor1
|
||||
icon.width: d.iconSize
|
||||
icon.height: d.iconSize
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property alias title: title.text
|
||||
property alias subtitle: subtitle.text
|
||||
|
||||
implicitHeight: layout.implicitHeight
|
||||
implicitWidth: layout.implicitWidth
|
||||
|
||||
ColumnLayout {
|
||||
id: layout
|
||||
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
StatusBaseText {
|
||||
id: title
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
color: Theme.palette.directColor1
|
||||
font {
|
||||
family: Theme.palette.baseFont.name
|
||||
pixelSize: 17
|
||||
bold: true
|
||||
}
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
id: subtitle
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: text !== ""
|
||||
color: Theme.palette.baseColor1
|
||||
font {
|
||||
family: Theme.palette.baseFont.name
|
||||
pixelSize: 15
|
||||
}
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
}
|
||||
}
|
||||