feat(@desktop): Fix twitchy scrolling issues

Close #6187
This commit is contained in:
MishkaRogachev 2022-07-14 14:03:36 +03:00 committed by Mikhail Rogachev
parent 0d3aed0611
commit 58e0fce819
47 changed files with 252 additions and 332 deletions

View File

@ -1,10 +1,11 @@
import QtQuick 2.1 import QtQuick 2.1
import QtGraphicalEffects 1.13 import QtGraphicalEffects 1.13
import utils 1.0 import StatusQ.Core 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import utils 1.0
import "../controls" import "../controls"
Rectangle { Rectangle {
@ -35,7 +36,7 @@ Rectangle {
height: listView.height height: listView.height
clip: true clip: true
ListView { StatusListView {
id: listView id: listView
orientation: ListView.Horizontal orientation: ListView.Horizontal
model: downloadsModel model: downloadsModel

View File

@ -1,5 +1,7 @@
import QtQuick 2.1 import QtQuick 2.1
import StatusQ.Core 0.1
import utils 1.0 import utils 1.0
import "../controls" import "../controls"
@ -15,7 +17,7 @@ import "../controls"
color: Style.current.background color: Style.current.background
ListView { StatusListView {
id: listView id: listView
anchors { anchors {
topMargin: Style.current.bigPadding topMargin: Style.current.bigPadding

View File

@ -1,10 +1,11 @@
import QtQuick 2.13 import QtQuick 2.13
import QtQuick.Layouts 1.13 import QtQuick.Layouts 1.13
import utils 1.0 import StatusQ.Core 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import utils 1.0
RowLayout { RowLayout {
id: favoritesBar id: favoritesBar
@ -17,15 +18,12 @@ RowLayout {
spacing: 0 spacing: 0
height: 38 height: 38
ListView { StatusListView {
id: bookmarkList id: bookmarkList
spacing: Style.current.halfPadding spacing: Style.current.halfPadding
orientation : ListView.Horizontal orientation : ListView.Horizontal
height: parent.height Layout.fillWidth: true
clip: true Layout.fillHeight: true
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
width: parent.width
boundsBehavior: Flickable.StopAtBounds
delegate: StatusFlatButton { delegate: StatusFlatButton {
id: favoriteBtn id: favoriteBtn
height: 32 height: 32

View File

@ -7,69 +7,63 @@ import StatusQ.Controls 0.1
import utils 1.0 import utils 1.0
StatusScrollView { StatusListView {
id: contactListPanel id: contactListPanel
property alias model: groupMembers.model
property string searchString property string searchString
property bool selectMode: true property bool selectMode: true
property var onItemChecked property var onItemChecked
property var selectedPubKeys: [] property var selectedPubKeys: []
spacing: 0
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: groupMembers.contentHeight > groupMembers.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
ListView { delegate: StatusListItem {
id: groupMembers id: contactDelegate
anchors.fill: parent
spacing: 0
clip: true
delegate: StatusListItem {
id: contactDelegate
property bool isChecked: selectedPubKeys.indexOf(model.pubKey) !== -1 property bool isChecked: selectedPubKeys.indexOf(model.pubKey) !== -1
visible: { visible: {
if (selectMode) { if (selectMode) {
return !searchString || model.displayName.toLowerCase().includes(searchString) return !searchString || model.displayName.toLowerCase().includes(searchString)
}
return checkbox.checked
} }
return checkbox.checked
}
title: !model.displayName.endsWith(".eth") && !!model.localNickname ? title: !model.displayName.endsWith(".eth") && !!model.localNickname ?
model.localNickname : Utils.removeStatusEns(model.displayName) model.localNickname : Utils.removeStatusEns(model.displayName)
image.source: Global.getProfileImage(model.pubKey) image.source: Global.getProfileImage(model.pubKey)
ringSettings.ringSpecModel: Utils.getColorHashAsJson(model.pubKey) ringSettings.ringSpecModel: Utils.getColorHashAsJson(model.pubKey)
height: visible ? implicitHeight : 0 height: visible ? implicitHeight : 0
function contactToggled(pubKey) { function contactToggled(pubKey) {
if (contactListPanel.selectMode) { if (contactListPanel.selectMode) {
let pubkeys = contactListPanel.selectedPubKeys let pubkeys = contactListPanel.selectedPubKeys
let idx = pubkeys.indexOf(pubKey) let idx = pubkeys.indexOf(pubKey)
if (idx === -1) { if (idx === -1) {
pubkeys.push(pubKey) pubkeys.push(pubKey)
} else if (idx > -1) { } else if (idx > -1) {
pubkeys.splice(idx, 1); pubkeys.splice(idx, 1);
} }
contactListPanel.selectedPubKeys = pubkeys contactListPanel.selectedPubKeys = pubkeys
}
}
components: [
StatusCheckBox {
id: checkbox
visible: contactListPanel.selectMode
checked: selectedPubKeys.indexOf(model.pubKey) !== -1
onClicked: {
contactDelegate.contactToggled(model.pubKey)
} }
} }
]
components: [ onClicked: {
StatusCheckBox { contactDelegate.contactToggled(model.pubKey)
id: checkbox
visible: contactListPanel.selectMode
checked: selectedPubKeys.indexOf(model.pubKey) !== -1
onClicked: {
contactDelegate.contactToggled(model.pubKey)
}
}
]
onClicked: {
contactDelegate.contactToggled(model.pubKey)
}
} }
} }
} }

View File

@ -1,6 +1,7 @@
import QtQuick 2.13 import QtQuick 2.13
import QtQuick.Layouts 1.13 import QtQuick.Layouts 1.13
import StatusQ.Core 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
@ -43,7 +44,7 @@ RowLayout {
} }
} }
ListView { StatusListView {
id: groupUsersModelListView id: groupUsersModelListView
visible: false visible: false
model: root.chatContentModule.usersModule.model model: root.chatContentModule.usersModule.model
@ -55,7 +56,7 @@ RowLayout {
} }
} }
ListView { StatusListView {
id: contactsModelListView id: contactsModelListView
visible: false visible: false
model: root.rootStore.contactsModel model: root.rootStore.contactsModel

View File

@ -22,12 +22,12 @@ import QtQuick.Controls 2.13
import QtGraphicalEffects 1.13 import QtGraphicalEffects 1.13
import QtQml.Models 2.13 import QtQml.Models 2.13
import utils 1.0 import StatusQ.Core 0.1
import shared.controls 1.0
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import utils 1.0
import shared 1.0 import shared 1.0
import shared.controls 1.0
import shared.panels 1.0 import shared.panels 1.0
import shared.controls.chat 1.0 import shared.controls.chat 1.0
@ -117,7 +117,7 @@ Rectangle {
cursorPosition: container.cursorPosition cursorPosition: container.cursorPosition
} }
ListView { StatusListView {
id: listView id: listView
model: mentionsListDelegate model: mentionsListDelegate
keyNavigationEnabled: true keyNavigationEnabled: true
@ -126,7 +126,6 @@ Rectangle {
anchors.leftMargin: Style.current.halfPadding anchors.leftMargin: Style.current.halfPadding
anchors.rightMargin: Style.current.halfPadding anchors.rightMargin: Style.current.halfPadding
anchors.bottomMargin: Style.current.halfPadding anchors.bottomMargin: Style.current.halfPadding
clip: true
Keys.priority: Keys.AfterItem Keys.priority: Keys.AfterItem
Keys.forwardTo: container.inputField Keys.forwardTo: container.inputField
Keys.onPressed: { Keys.onPressed: {

View File

@ -1,6 +1,8 @@
import QtQuick 2.13 import QtQuick 2.13
import utils 1.0 import utils 1.0
import StatusQ.Core 0.1
Item { Item {
id: suggestionsPanelRoot id: suggestionsPanelRoot
property alias model: filterModel property alias model: filterModel
@ -17,7 +19,7 @@ Item {
onSourceModelChanged: invalidateFilter() onSourceModelChanged: invalidateFilter()
Component.onCompleted: invalidateFilter() Component.onCompleted: invalidateFilter()
ListView { StatusListView {
// This is a fake list (invisible), used just for the sake of accessing items of the `sourceModel` // This is a fake list (invisible), used just for the sake of accessing items of the `sourceModel`
// without exposing explicit methods from the model which would return item detail. // without exposing explicit methods from the model which would return item detail.
// In general the whole thing about preparing/displaying suggestion panel and list there should // In general the whole thing about preparing/displaying suggestion panel and list there should

View File

@ -1,16 +1,16 @@
import QtQuick 2.13 import QtQuick 2.13
import QtQuick.Controls 2.13 import QtQuick.Controls 2.13
import StatusQ.Components 0.1
import shared 1.0
import shared.panels 1.0
import shared.status 1.0
import utils 1.0
import "../controls"
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import shared 1.0
import shared.panels 1.0
import shared.status 1.0
import utils 1.0
import "../controls"
Item { Item {
id: root id: root
@ -39,12 +39,8 @@ Item {
text: root.label text: root.label
} }
ListView { StatusListView {
id: userListView id: userListView
clip: true
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded
}
anchors { anchors {
top: titleText.bottom top: titleText.bottom
topMargin: Style.current.padding topMargin: Style.current.padding
@ -53,7 +49,7 @@ Item {
bottom: parent.bottom bottom: parent.bottom
bottomMargin: Style.current.bigPadding bottomMargin: Style.current.bigPadding
} }
boundsBehavior: Flickable.StopAtBounds
model: usersModule.model model: usersModule.model
section.property: "onlineStatus" section.property: "onlineStatus"
section.delegate: (root.width > 58) ? sectionDelegateComponent : null section.delegate: (root.width > 58) ? sectionDelegateComponent : null

View File

@ -51,7 +51,7 @@ StatusScrollView {
ColumnLayout { ColumnLayout {
id: layout id: layout
width: root.width width: root.availableWidth
spacing: 12 spacing: 12
CommunityNameInput { CommunityNameInput {

View File

@ -78,14 +78,13 @@ SettingsPageLayout {
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1
} }
ListView { StatusListView {
id: memberList id: memberList
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
model: root.membersModel model: root.membersModel
clip: true
// TODO: use StatusMemberListItem (it does not behave correctly right now) // TODO: use StatusMemberListItem (it does not behave correctly right now)
delegate: StatusListItem { delegate: StatusListItem {

View File

@ -3,10 +3,10 @@ import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13 import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13 import QtGraphicalEffects 1.13
import utils 1.0 import StatusQ.Core 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import utils 1.0
import shared.popups 1.0 import shared.popups 1.0
import "../panels" import "../panels"
@ -19,7 +19,7 @@ ModalPopup {
title: qsTr("Contact requests") title: qsTr("Contact requests")
ListView { StatusListView {
id: contactList id: contactList
anchors.fill: parent anchors.fill: parent
@ -27,7 +27,6 @@ ModalPopup {
anchors.rightMargin: -Style.current.halfPadding anchors.rightMargin: -Style.current.halfPadding
model: popup.store.contactRequestsModel model: popup.store.contactRequestsModel
clip: true
delegate: ContactRequestPanel { delegate: ContactRequestPanel {
contactPubKey: model.pubKey contactPubKey: model.pubKey

View File

@ -193,11 +193,10 @@ StatusModal {
visible: pinnedMessagesBtn.visible visible: pinnedMessagesBtn.visible
} }
ListView { StatusListView {
id: memberList id: memberList
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
clip: true
model: popup.chatContentModule.usersModule.model model: popup.chatContentModule.usersModule.model
delegate: StatusListItem { delegate: StatusListItem {
id: contactRow id: contactRow

View File

@ -1,6 +1,9 @@
import QtQuick 2.13 import QtQuick 2.13
import QtQuick.Controls 2.3 import QtQuick.Controls 2.3
import StatusQ.Core 0.1
import StatusQ.Controls 0.1 as StatusQControls
import utils 1.0 import utils 1.0
import shared 1.0 import shared 1.0
import shared.views 1.0 import shared.views 1.0
@ -13,8 +16,6 @@ import "../panels"
//TODO remove or make view? //TODO remove or make view?
import "../views" import "../views"
import StatusQ.Controls 0.1 as StatusQControls
// TODO: replace with StatusMOdal // TODO: replace with StatusMOdal
ModalPopup { ModalPopup {
id: popup id: popup
@ -83,7 +84,7 @@ ModalPopup {
id: pinButtonGroup id: pinButtonGroup
} }
ListView { StatusListView {
id: pinnedMessageListView id: pinnedMessageListView
model: popup.pinnedMessagesModel model: popup.pinnedMessagesModel
height: parent.height height: parent.height
@ -94,7 +95,6 @@ ModalPopup {
topMargin: Style.current.halfPadding topMargin: Style.current.halfPadding
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: -Style.current.halfPadding anchors.topMargin: -Style.current.halfPadding
clip: true
delegate: Item { delegate: Item {
id: messageDelegate id: messageDelegate

View File

@ -8,7 +8,6 @@ import StatusQ.Controls 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Popups 0.1 import StatusQ.Popups 0.1
import utils 1.0 import utils 1.0
import shared 1.0 import shared 1.0
@ -76,11 +75,10 @@ StatusModal {
bottomPadding: 8 bottomPadding: 8
height: 400 height: 400
ListView { StatusListView {
anchors.fill: parent anchors.fill: parent
model: communitiesDelegateModel model: communitiesDelegateModel
spacing: 4 spacing: 4
clip: true
id: communitiesList id: communitiesList
section.property: "name" section.property: "name"

View File

@ -8,7 +8,6 @@ import StatusQ.Components 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Popups 0.1 import StatusQ.Popups 0.1
import utils 1.0 import utils 1.0
StatusModal { StatusModal {
@ -115,11 +114,10 @@ StatusModal {
height: 300 height: 300
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ListView { StatusListView {
id: chatList id: chatList
anchors.fill: parent anchors.fill: parent
model: community.chats model: community.chats
boundsBehavior: Flickable.StopAtBounds
delegate: StatusListItem { delegate: StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
title: "#" + model.name title: "#" + model.name

View File

@ -106,7 +106,7 @@ StatusModal {
} }
} }
ListView { StatusListView {
id: communityChannelList id: communityChannelList
anchors.top: channelsLabel.bottom anchors.top: channelsLabel.bottom
@ -114,7 +114,6 @@ StatusModal {
width: parent.width width: parent.width
model: isEdit ? root.store.chatCommunitySectionModule.editCategoryChannelsModel : root.store.chatCommunitySectionModule.model model: isEdit ? root.store.chatCommunitySectionModule.editCategoryChannelsModel : root.store.chatCommunitySectionModule.model
interactive: false interactive: false
clip: true
delegate: StatusListItem { delegate: StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter

View File

@ -7,7 +7,6 @@ import StatusQ.Controls 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Popups 0.1 import StatusQ.Popups 0.1
import utils 1.0 import utils 1.0
import shared 1.0 import shared 1.0
@ -50,7 +49,7 @@ StatusModal {
bottomPadding: 8 bottomPadding: 8
height: 300 height: 300
ListView { StatusListView {
id: membershipRequestList id: membershipRequestList
anchors.fill: parent anchors.fill: parent
model: popup.communityData.pendingRequestsToJoin model: popup.communityData.pendingRequestsToJoin

View File

@ -6,6 +6,10 @@ import QtQml.Models 2.13
import QtGraphicalEffects 1.13 import QtGraphicalEffects 1.13
import QtQuick.Dialogs 1.3 import QtQuick.Dialogs 1.3
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import utils 1.0 import utils 1.0
import shared 1.0 import shared 1.0
import shared.views 1.0 import shared.views 1.0
@ -14,8 +18,6 @@ import shared.popups 1.0
import shared.status 1.0 import shared.status 1.0
import shared.controls 1.0 import shared.controls 1.0
import shared.views.chat 1.0 import shared.views.chat 1.0
import StatusQ.Core 0.1
import StatusQ.Components 0.1
import "../controls" import "../controls"
@ -93,15 +95,13 @@ Item {
} }
} }
ListView { StatusListView {
id: chatLogView id: chatLogView
anchors.top: loadingMessagesIndicator.bottom anchors.top: loadingMessagesIndicator.bottom
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
spacing: 0 spacing: 0
boundsBehavior: Flickable.StopAtBounds
clip: true
verticalLayoutDirection: ListView.BottomToTop verticalLayoutDirection: ListView.BottomToTop
// This header and Connections is to create an invisible padding so that the chat identifier is at the top // This header and Connections is to create an invisible padding so that the chat identifier is at the top
@ -124,7 +124,7 @@ Item {
} }
} }
ScrollBar.vertical: ScrollBar { ScrollBar.vertical: StatusScrollBar {
visible: chatLogView.visibleArea.heightRatio < 1 visible: chatLogView.visibleArea.heightRatio < 1
} }

View File

@ -101,7 +101,7 @@ Item {
} }
StatusScrollView { StatusScrollView {
id: chatGroupsContainer id: scrollView
anchors.top: membershipRequests.bottom anchors.top: membershipRequests.bottom
anchors.topMargin: Style.current.padding anchors.topMargin: Style.current.padding
anchors.bottom: createChatOrCommunity.top anchors.bottom: createChatOrCommunity.top
@ -362,7 +362,7 @@ Item {
Column { Column {
id: bannerColumn id: bannerColumn
width: parent.width width: scrollView.availableWidth
anchors.top: communityChatListAndCategories.bottom anchors.top: communityChatListAndCategories.bottom
anchors.topMargin: Style.current.padding anchors.topMargin: Style.current.padding
spacing: Style.current.bigPadding spacing: Style.current.bigPadding

View File

@ -68,7 +68,7 @@ StatusAppTwoPanelLayout {
text: qsTr("Settings") text: qsTr("Settings")
} }
ListView { StatusListView {
id: listView id: listView
Layout.fillWidth: true Layout.fillWidth: true

View File

@ -2,6 +2,11 @@ import QtQuick 2.13
import QtQuick.Controls 2.13 import QtQuick.Controls 2.13
import QtQuick.Layouts 1.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 StatusQ.Popups 0.1
import utils 1.0 import utils 1.0
import shared 1.0 import shared 1.0
@ -11,12 +16,6 @@ import "../panels"
import "../popups" import "../popups"
import "../popups/community" import "../popups/community"
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Popups 0.1
Item { Item {
id: root id: root
width: 304 width: 304
@ -139,15 +138,13 @@ Item {
// chat list // chat list
StatusScrollView { StatusScrollView {
id: scrollView id: scroll
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
StatusChatList { StatusChatList {
id: channelList id: channelList
width: scrollView.availableWidth width: scroll.availableWidth
model: root.chatSectionModule.model model: root.chatSectionModule.model
highlightItem: !root.store.openCreateChat highlightItem: !root.store.openCreateChat
onChatItemSelected: { onChatItemSelected: {
@ -234,15 +231,6 @@ Item {
} }
} }
} }
EmptyViewPanel {
id: emptyViewAndSuggestions
visible: !localAccountSensitiveSettings.hideChannelSuggestions
anchors.top: channelList.bottom
anchors.topMargin: Style.current.padding
rootStore: root.store
onSuggestedMessageClicked: chatSectionModule.createPublicChat(channel)
}
} }
} }

View File

@ -25,7 +25,7 @@ Page {
root.rootStore.openCreateChat = false; root.rootStore.openCreateChat = false;
} }
ListView { StatusListView {
id: contactsModelListView id: contactsModelListView
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right

View File

@ -46,7 +46,7 @@ StatusStackModal {
ColumnLayout { ColumnLayout {
id: generalViewLayout id: generalViewLayout
width: generalView.width width: generalView.availableWidth
spacing: 12 spacing: 12
CommunityNameInput { CommunityNameInput {

View File

@ -1,11 +1,13 @@
import QtQuick 2.13 import QtQuick 2.13
import QtQuick.Controls 2.13 import QtQuick.Controls 2.13
import "../controls" import StatusQ.Core 0.1
import utils 1.0 import utils 1.0
ListView { import "../controls"
StatusListView {
id: accountsView id: accountsView
property var isSelected: function () {} property var isSelected: function () {}

View File

@ -9,13 +9,12 @@ import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Popups 0.1 import StatusQ.Popups 0.1
import shared.panels 1.0 import shared.panels 1.0
import shared 1.0 import shared 1.0
import shared.popups 1.0 import shared.popups 1.0
import utils 1.0
import shared.controls 1.0 import shared.controls 1.0
import utils 1.0
import "../popups" import "../popups"
import "../stores" import "../stores"
import "../shared" import "../shared"
@ -40,7 +39,7 @@ Item {
Loader { Loader {
active: !OnboardingStore.onboardingModuleInst.importedAccountPubKey active: !OnboardingStore.onboardingModuleInst.importedAccountPubKey
sourceComponent: ListView { sourceComponent: StatusListView {
model: OnboardingStore.onboardingModuleInst.accountsModel model: OnboardingStore.onboardingModuleInst.accountsModel
delegate: Item { delegate: Item {
Component.onCompleted: { Component.onCompleted: {

View File

@ -9,7 +9,7 @@ import StatusQ.Popups 0.1
import utils 1.0 import utils 1.0
ListView { StatusListView {
id: root id: root
property bool hasAddedContacts: false property bool hasAddedContacts: false

View File

@ -3,12 +3,14 @@ import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13 import QtQuick.Layouts 1.13
import QtQml.Models 2.13 import QtQml.Models 2.13
import StatusQ.Core 0.1
import utils 1.0 import utils 1.0
import shared 1.0 import shared 1.0
import shared.popups 1.0 import shared.popups 1.0
import shared.panels 1.0 import shared.panels 1.0
import "../../Chat/popups"
import "../../Chat/popups"
import "." import "."
Item { Item {
@ -89,14 +91,13 @@ Item {
delegate: contactPanelComponent delegate: contactPanelComponent
} }
ListView { StatusListView {
id: contactsList id: contactsList
anchors.top: title.bottom anchors.top: title.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
interactive: false interactive: false
clip: true
ScrollBar.vertical: ScrollBar { ScrollBar.vertical: ScrollBar {
policy: contactListRoot.scrollbarOn ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded policy: contactListRoot.scrollbarOn ? ScrollBar.AlwaysOn : ScrollBar.AsNeeded
} }

View File

@ -55,11 +55,10 @@ ModalPopup {
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: ensNames.contentHeight > ensNames.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff ScrollBar.vertical.policy: ensNames.contentHeight > ensNames.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
ListView { StatusListView {
anchors.fill: parent anchors.fill: parent
model: root.ensUsernamesStore.ensUsernamesModel model: root.ensUsernamesStore.ensUsernamesModel
spacing: 0 spacing: 0
clip: true
id: ensNames id: ensNames
delegate: RadioDelegate { delegate: RadioDelegate {
id: radioDelegate id: radioDelegate

View File

@ -3,13 +3,12 @@ import QtQuick.Controls 2.13
import QtGraphicalEffects 1.13 import QtGraphicalEffects 1.13
import QtQuick.Layouts 1.13 import QtQuick.Layouts 1.13
import utils 1.0
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import utils 1.0
import shared 1.0 import shared 1.0
import shared.panels 1.0 import shared.panels 1.0
import shared.popups 1.0 import shared.popups 1.0
@ -28,7 +27,7 @@ ModalPopup {
root.destroy() root.destroy()
} }
ListView { StatusListView {
id: mutedChatsList id: mutedChatsList
anchors.fill: parent anchors.fill: parent
model: root.model model: root.model

View File

@ -24,7 +24,7 @@ StatusScrollView {
ColumnLayout { ColumnLayout {
id: column id: column
width: parent.width width: root.availableWidth
spacing: Style.current.padding spacing: Style.current.padding
StyledText { StyledText {

View File

@ -155,7 +155,7 @@ SettingsContentBase {
color: Theme.palette.directColor1 color: Theme.palette.directColor1
} }
ListView { StatusListView {
id: listView id: listView
anchors.top: deviceListLbl.bottom anchors.top: deviceListLbl.bottom
anchors.topMargin: Style.current.padding anchors.topMargin: Style.current.padding

View File

@ -2,18 +2,18 @@ import QtQuick 2.14
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import QtQuick.Controls 2.14 import QtQuick.Controls 2.14
import utils 1.0
import StatusQ.Core 0.1 import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1 import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import "../popups"
import shared 1.0 import shared 1.0
import shared.panels 1.0 import shared.panels 1.0
import shared.views.chat 1.0 import shared.views.chat 1.0
import shared.panels.chat 1.0 import shared.panels.chat 1.0
import shared.controls.chat 1.0 import shared.controls.chat 1.0
import utils 1.0
import "../popups"
Item { Item {
id: root id: root
@ -186,27 +186,21 @@ Item {
} }
Item { Item {
id: ensList
anchors.top: usernamesLabel.bottom anchors.top: usernamesLabel.bottom
anchors.topMargin: 10 anchors.topMargin: 10
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
height: 200 height: 200
id: ensList
StatusScrollView { StatusListView {
id: lvEns
anchors.fill: parent anchors.fill: parent
model: root.ensUsernamesStore.ensUsernamesModel
spacing: 10
delegate: ensDelegate
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded }
ScrollBar.vertical.policy: lvEns.contentHeight > lvEns.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
ListView {
id: lvEns
anchors.fill: parent
model: root.ensUsernamesStore.ensUsernamesModel
spacing: 10
clip: true
delegate: ensDelegate
}
} }
} }

View File

@ -535,11 +535,10 @@ SettingsContentBase {
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1
} }
ListView { StatusListView {
Layout.preferredWidth: root.contentWidth Layout.preferredWidth: root.contentWidth
Layout.preferredHeight: 400 Layout.preferredHeight: 400
visible: root.notificationsStore.exemptionsModel.count > 0 visible: root.notificationsStore.exemptionsModel.count > 0
clip: true
model: root.notificationsStore.exemptionsModel model: root.notificationsStore.exemptionsModel
delegate: exemptionDelegateComponent delegate: exemptionDelegateComponent

View File

@ -105,37 +105,32 @@ Item {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.topMargin: Style.current.bigPadding anchors.topMargin: Style.current.bigPadding
padding: 0
width: root.contentWidth width: root.contentWidth
StatusScrollView { Column {
id: contentFliackable id: contentLayout
contentWidth: Math.max(contentLayout.implicitWidth, scrollView.width) width: scrollView.availableWidth
contentHeight: Math.max(contentLayout.implicitHeight, scrollView.height) + scrollView.anchors.topMargin
Column { MouseArea {
id: contentLayout onClicked: root.baseAreaClicked()
anchors.fill: parent.contentItem width: contentWrapper.implicitWidth
height: contentWrapper.implicitHeight
MouseArea { Column {
onClicked: root.baseAreaClicked() id: contentWrapper
width: contentWrapper.implicitWidth
height: contentWrapper.implicitHeight
Column {
id: contentWrapper
}
} }
}
Item { Item {
// This is a settingsDirtyToastMessage placeholder // This is a settingsDirtyToastMessage placeholder
width: settingsDirtyToastMessage.implicitWidth width: settingsDirtyToastMessage.implicitWidth
height: settingsDirtyToastMessage.active ? settingsDirtyToastMessage.implicitHeight : 0 height: settingsDirtyToastMessage.active ? settingsDirtyToastMessage.implicitHeight : 0
Behavior on implicitHeight { Behavior on implicitHeight {
NumberAnimation { NumberAnimation {
duration: 150 duration: 150
easing.type: Easing.InOutQuad easing.type: Easing.InOutQuad
}
} }
} }
} }
@ -147,7 +142,7 @@ Item {
anchors.bottom: scrollView.bottom anchors.bottom: scrollView.bottom
anchors.horizontalCenter: scrollView.horizontalCenter anchors.horizontalCenter: scrollView.horizontalCenter
active: root.dirty active: root.dirty
flickable: contentFliackable flickable: scrollView
saveChangesButtonEnabled: root.saveChangesButtonEnabled saveChangesButtonEnabled: root.saveChangesButtonEnabled
onResetChangesClicked: root.resetChangesClicked() onResetChangesClicked: root.resetChangesClicked()
onSaveChangesClicked: root.saveChangesClicked() onSaveChangesClicked: root.saveChangesClicked()

View File

@ -40,7 +40,7 @@ StatusModal {
text: qsTr("Choose a service you'd like to use to buy crypto") text: qsTr("Choose a service you'd like to use to buy crypto")
} }
ListView { StatusListView {
anchors.top: note.bottom anchors.top: note.bottom
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.topMargin: Style.current.padding anchors.topMargin: Style.current.padding
@ -49,7 +49,6 @@ StatusModal {
model: RootStore.cryptoRampServicesModel model: RootStore.cryptoRampServicesModel
focus: true focus: true
spacing: Style.current.padding spacing: Style.current.padding
clip: true
delegate: StatusListItem { delegate: StatusListItem {
width: parent.width width: parent.width

View File

@ -3,16 +3,16 @@ import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13 import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13 import QtGraphicalEffects 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import utils 1.0 import utils 1.0
import shared 1.0 import shared 1.0
import shared.panels 1.0 import shared.panels 1.0
import shared.controls 1.0 import shared.controls 1.0
import StatusQ.Components 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import "../controls" import "../controls"
import "../popups" import "../popups"
import "../stores" import "../stores"
@ -79,62 +79,51 @@ Rectangle {
} }
} }
ScrollView { StatusListView {
spacing: Style.current.smallPadding
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
Layout.topMargin: Style.current.halfPadding Layout.topMargin: Style.current.halfPadding
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: listView.contentHeight > listView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
clip: true
ListView { delegate: StatusListItem {
id: listView width: ListView.view.width
highlighted: RootStore.currentAccount.name === model.name
spacing: Style.current.smallPadding title: model.name
anchors.top: parent.top subTitle: Utils.toLocaleString(model.currencyBalance.toFixed(2), RootStore.locale, {"model.currency": true}) + " " + RootStore.currentCurrency.toUpperCase()
width: parent.width icon.emoji: !!model.emoji ? model.emoji: ""
height: parent.height icon.color: model.color
boundsBehavior: Flickable.StopAtBounds icon.name: !model.emoji ? "filled-account": ""
clip: true icon.letterSize: 14
icon.isLetterIdenticon: !!model.emoji ? true : false
delegate: StatusListItem { icon.background.color: Theme.palette.primaryColor3
width: ListView.view.width statusListItemTitle.font.weight: Font.Medium
highlighted: RootStore.currentAccount.name === model.name color: sensor.containsMouse || highlighted ? Theme.palette.baseColor3 : "transparent"
title: model.name onClicked: {
subTitle: Utils.toLocaleString(model.currencyBalance.toFixed(2), RootStore.locale, {"model.currency": true}) + " " + RootStore.currentCurrency.toUpperCase() changeSelectedAccount(index)
icon.emoji: !!model.emoji ? model.emoji: "" showSavedAddresses(false)
icon.color: model.color
icon.name: !model.emoji ? "filled-account": ""
icon.letterSize: 14
icon.isLetterIdenticon: !!model.emoji ? true : false
icon.background.color: Theme.palette.primaryColor3
statusListItemTitle.font.weight: Font.Medium
color: sensor.containsMouse || highlighted ? Theme.palette.baseColor3 : "transparent"
onClicked: {
changeSelectedAccount(index)
showSavedAddresses(false)
}
} }
footer: Item {
width: ListView.view.width
height: addAccountBtn.height + Style.current.xlPadding
StatusButton {
id: addAccountBtn
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: Style.current.bigPadding
font.pixelSize: 15
font.weight: Font.Medium
icon.name: "add"
text: qsTr("Add account")
onClicked: addAccountModal.open()
}
}
model: RootStore.accounts
// model: RootStore.exampleWalletModel
} }
footer: Item {
width: ListView.view.width
height: addAccountBtn.height + Style.current.xlPadding
StatusButton {
id: addAccountBtn
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: Style.current.bigPadding
font.pixelSize: 15
font.weight: Font.Medium
icon.name: "add"
text: qsTr("Add account")
onClicked: addAccountModal.open()
}
}
model: RootStore.accounts
// model: RootStore.exampleWalletModel
} }
Item { Layout.fillHeight: true } Item { Layout.fillHeight: true }
@ -151,4 +140,4 @@ Rectangle {
onClicked: showSavedAddresses(true) onClicked: showSavedAddresses(true)
} }
} }
} }

View File

@ -225,7 +225,8 @@ Item {
text: qsTr("No saved addresses") text: qsTr("No saved addresses")
} }
StatusScrollView { StatusListView {
id: listView
anchors.top: errorMessage.bottom anchors.top: errorMessage.bottom
anchors.topMargin: Style.current.padding anchors.topMargin: Style.current.padding
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@ -233,14 +234,8 @@ Item {
anchors.right: parent.right anchors.right: parent.right
anchors.left: parent.left anchors.left: parent.left
visible: listView.count > 0 visible: listView.count > 0
spacing: 5
ListView { model: RootStore.savedAddresses
id: listView delegate: delegateSavedAddress
model: RootStore.savedAddresses
spacing: 5
width: parent.width
boundsBehavior: Flickable.StopAtBounds
delegate: delegateSavedAddress
}
} }
} }

View File

@ -67,16 +67,13 @@ StackDetailBase {
} }
} }
ListView { StatusListView {
anchors.top: collectibleImageDetails.bottom anchors.top: collectibleImageDetails.bottom
anchors.topMargin: 32 anchors.topMargin: 32
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.bottomMargin: 20 anchors.bottomMargin: 20
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
width: parent.width width: parent.width
clip: true
boundsBehavior: Flickable.StopAtBounds
model: 3 model: 3
delegate: StatusExpandableItem { delegate: StatusExpandableItem {
width: parent.width width: parent.width

View File

@ -939,7 +939,7 @@ Item {
} }
} }
ListView { StatusListView {
id: toastArea id: toastArea
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 60 anchors.topMargin: 60

View File

@ -402,7 +402,8 @@ Rectangle {
property int copyTextStart: 0 property int copyTextStart: 0
property string copiedTextPlain: "" property string copiedTextPlain: ""
property string copiedTextFormatted: "" property string copiedTextFormatted: ""
ListView {
StatusListView {
id: dummyContactList id: dummyContactList
model: control.usersStore ? control.usersStore.usersModel : [] model: control.usersStore ? control.usersStore.usersModel : []
delegate: Item { delegate: Item {
@ -931,6 +932,7 @@ Rectangle {
StatusScrollView { StatusScrollView {
id: scrollView id: scrollView
padding: 0
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: profileImage.visible ? profileImage.right : parent.left anchors.left: profileImage.visible ? profileImage.right : parent.left

View File

@ -4,6 +4,8 @@ import QtGraphicalEffects 1.12
import QtQuick.Dialogs 1.3 import QtQuick.Dialogs 1.3
import QtQuick.Layouts 1.13 import QtQuick.Layouts 1.13
import StatusQ.Core 0.1
import utils 1.0 import utils 1.0
import shared 1.0 import shared 1.0
import shared.panels 1.0 import shared.panels 1.0
@ -128,16 +130,14 @@ Popup {
} }
} }
ListView { StatusListView {
id: listView id: listView
model: popup.modelList || [] model: popup.modelList || []
keyNavigationEnabled: true keyNavigationEnabled: true
Layout.fillHeight: true
width: parent.width width: parent.width
anchors.top: searchBox.bottom anchors.top: searchBox.bottom
anchors.topMargin: searchBox.visible ? Style.current.smallPadding : 0 anchors.topMargin: searchBox.visible ? Style.current.smallPadding : 0
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
clip: true
delegate: Rectangle { delegate: Rectangle {
property variant myData: typeof modelData === "undefined" ? model : modelData property variant myData: typeof modelData === "undefined" ? model : modelData

View File

@ -99,7 +99,7 @@ Popup {
onTextChanged: if (text === "") listView.currentIndex = 0 onTextChanged: if (text === "") listView.currentIndex = 0
} }
ListView { StatusListView {
id: listView id: listView
Layout.fillWidth: true Layout.fillWidth: true
@ -107,7 +107,6 @@ Popup {
property bool selectByHover: false property bool selectByHover: false
clip: true
highlightMoveDuration: 200 highlightMoveDuration: 200
delegate: Item { delegate: Item {

View File

@ -233,7 +233,6 @@ Popup {
id: installedStickersSV id: installedStickersSV
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
height: 32 height: 32
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
RowLayout { RowLayout {
id: stickersRowLayout id: stickersRowLayout

View File

@ -15,22 +15,17 @@ Item {
height: assetListView.height height: assetListView.height
StatusScrollView { StatusListView {
id: assetListView
anchors.fill: parent anchors.fill: parent
model: account.assets
delegate: AssetDelegate {
locale: RootStore.locale
currency: RootStore.currentCurrency
}
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: assetListView.contentHeight > assetListView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
ListView { ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded }
id: assetListView
anchors.fill: parent
model: account.assets
delegate: AssetDelegate {
locale: RootStore.locale
currency: RootStore.currentCurrency
}
boundsBehavior: Flickable.StopAtBounds
}
} }
} }

View File

@ -31,42 +31,36 @@ Item {
return parts.some(p => p.startsWith(filter)) return parts.some(p => p.startsWith(filter))
} }
StatusListView {
StatusScrollView { id: contactListView
anchors.fill: parent anchors.fill: parent
spacing: 0
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff model: root.contactsStore.myContactsModel
ScrollBar.vertical.policy: contactListView.contentHeight > contactListView.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff delegate: Contact {
showCheckbox: root.showCheckbox
ListView { isChecked: root.pubKeys.indexOf(model.pubKey) > -1
anchors.fill: parent pubKey: model.pubKey
spacing: 0 isContact: model.isContact
clip: true isUser: false
id: contactListView name: model.displayName
model: root.contactsStore.myContactsModel image: model.icon
delegate: Contact { isVisible: {
showCheckbox: root.showCheckbox return model.isContact && !model.isBlocked && (root.filterText === "" ||
isChecked: root.pubKeys.indexOf(model.pubKey) > -1 root.matchesAlias(model.alias.toLowerCase(), root.filterText.toLowerCase()) ||
pubKey: model.pubKey model.displayName.toLowerCase().includes(root.filterText.toLowerCase()) ||
isContact: model.isContact model.ensName.toLowerCase().includes(root.filterText.toLowerCase()) ||
isUser: false model.localNickname.toLowerCase().includes(root.filterText.toLowerCase()) ||
name: model.displayName model.pubKey.toLowerCase().includes(root.filterText.toLowerCase())) &&
image: model.icon (!root.hideCommunityMembers ||
isVisible: { !root.community.hasMember(model.pubKey))
return model.isContact && !model.isBlocked && (root.filterText === "" || }
root.matchesAlias(model.alias.toLowerCase(), root.filterText.toLowerCase()) || onContactClicked: function () {
model.displayName.toLowerCase().includes(root.filterText.toLowerCase()) || root.contactClicked(model)
model.ensName.toLowerCase().includes(root.filterText.toLowerCase()) ||
model.localNickname.toLowerCase().includes(root.filterText.toLowerCase()) ||
model.pubKey.toLowerCase().includes(root.filterText.toLowerCase())) &&
(!root.hideCommunityMembers ||
!root.community.hasMember(model.pubKey))
}
onContactClicked: function () {
root.contactClicked(model)
}
} }
} }
ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded }
} }
} }

View File

@ -2,11 +2,12 @@ import QtQuick 2.13
import QtQuick.Controls 2.1 import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import utils 1.0 import StatusQ.Core 0.1
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import StatusQ.Controls 0.1 import StatusQ.Controls 0.1
import utils 1.0
import "../panels" import "../panels"
import "../popups" import "../popups"
import "../stores" import "../stores"
@ -68,15 +69,13 @@ Item {
font.pixelSize: Style.current.primaryTextFontSize font.pixelSize: Style.current.primaryTextFontSize
} }
ListView { StatusListView {
id: transactionListRoot id: transactionListRoot
anchors.top: noTxs.bottom anchors.top: noTxs.bottom
anchors.topMargin: Style.current.padding anchors.topMargin: Style.current.padding
anchors.bottom: loadMoreButton.top anchors.bottom: loadMoreButton.top
anchors.bottomMargin: Style.current.padding anchors.bottomMargin: Style.current.padding
width: parent.width width: parent.width
clip: true
boundsBehavior: Flickable.StopAtBounds
model: RootStore.historyTransactions model: RootStore.historyTransactions
delegate: TransactionDelegate { delegate: TransactionDelegate {
tokens: RootStore.tokens tokens: RootStore.tokens

View File

@ -62,7 +62,7 @@ Item {
color: "transparent" color: "transparent"
radius: 8 radius: 8
ListView { StatusListView {
id: savedAddresses id: savedAddresses
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
@ -70,10 +70,8 @@ Item {
height: Math.min(288, savedAddresses.contentHeight) height: Math.min(288, savedAddresses.contentHeight)
model: root.store.savedAddressesModel model: root.store.savedAddressesModel
clip: true
header: savedAddresses.count > 0 ? search : nothingInList header: savedAddresses.count > 0 ? search : nothingInList
headerPositioning: ListView.OverlayHeader headerPositioning: ListView.OverlayHeader
boundsBehavior: Flickable.StopAtBounds
delegate: StatusListItem { delegate: StatusListItem {
width: visible ? parent.width: 0 width: visible ? parent.width: 0
height: visible ? 64 : 0 height: visible ? 64 : 0
@ -120,16 +118,13 @@ Item {
color: "transparent" color: "transparent"
radius: 8 radius: 8
ListView { StatusListView {
id: myAccounts id: myAccounts
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
width: parent.width width: parent.width
height: Math.min(288, myAccounts.contentHeight) height: Math.min(288, myAccounts.contentHeight)
boundsBehavior: Flickable.StopAtBounds
clip: true
delegate: StatusListItem { delegate: StatusListItem {
width: visible ? parent.width: 0 width: visible ? parent.width: 0
height: visible ? 64 : 0 height: visible ? 64 : 0
@ -155,16 +150,13 @@ Item {
color: "transparent" color: "transparent"
radius: 8 radius: 8
ListView { StatusListView {
id: recents id: recents
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
width: parent.width width: parent.width
height: Math.min(288, recents.contentHeight) height: Math.min(288, recents.contentHeight)
boundsBehavior: Flickable.StopAtBounds
clip: true
header: StatusBaseText { header: StatusBaseText {
font.pixelSize: 15 font.pixelSize: 15
color: Theme.palette.directColor1 color: Theme.palette.directColor1