fix(CreateCategoryPopup): ensure delete button and name input stay in viewport

There are a few issues with the popup's content when there are many channels in a community:

1. Channel items belonging to other categories would still take space in the list
1. Due to the longer list of channels, the delete button wouldn't be fully visible (scrolling down
   helps here)
2. Scrolling down is hard because the `ListView` in use is `interactive`
3. Even when `interactive` is set to false, one would scroll the name input out of the viewport.

To solve these, this commit rearchitects the popup's content such that:

1. The name input is always static and in place
2. The scrollview starts with the channel list and ends with the channel list
3. The delete button is positioned below the scrollview
4. The scrollview has a max height of 300 so that the popup doesn't grow too big
5. Invisible channel items won't have a height anymore

The result is that the middle section of the popup becomes scrollable in case there's many
channel items, while both, the name input and the delete button stay in the viewport.

Fixes #3013
This commit is contained in:
Pascal Precht 2021-07-22 13:53:08 +02:00 committed by Iuri Matias
parent a406a24df5
commit 9f6a4f7834
1 changed files with 140 additions and 133 deletions

View File

@ -48,166 +48,173 @@ StatusModal {
//% "New category"
qsTrId("new-category")
content: ScrollView {
id: scrollView
content: Column {
width: popup.width
height: Math.min(content.height, 432)
property ScrollBar vScrollBar: ScrollBar.vertical
property alias categoryName: nameInput
contentHeight: content.height
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
clip: true
Item {
width: parent.width
height: 76
Input {
id: nameInput
width: parent.width -32
function scrollBackUp() {
vScrollBar.setPosition(0)
anchors.centerIn: parent
anchors.left: undefined
anchors.right: undefined
//% "Category title"
placeholderText: qsTrId("category-title")
maxLength: maxCategoryNameLength
onTextEdited: {
validationError = Utils.validateAndReturnError(text,
categoryNameValidator,
//% "category name"
qsTrId("category-name"),
maxCategoryNameLength)
}
}
}
Column {
id: content
width: parent.width
StatusModalDivider {
topPadding: 8
bottomPadding: 8
}
StatusModalDivider {
bottomPadding: 8
ScrollView {
id: scrollView
width: popup.width
height: Math.min(content.height, 300)
anchors.horizontalCenter: parent.horizontalCenter
property ScrollBar vScrollBar: ScrollBar.vertical
contentHeight: content.height
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
clip: true
function scrollBackUp() {
vScrollBar.setPosition(0)
}
Item {
id: content
width: parent.width
height: 76
Input {
id: nameInput
width: parent.width -32
height: channelsLabel.height + communityChannelList.height
anchors.centerIn: parent
anchors.left: undefined
anchors.right: undefined
//% "Category title"
placeholderText: qsTrId("category-title")
maxLength: maxCategoryNameLength
onTextEdited: {
validationError = Utils.validateAndReturnError(text,
categoryNameValidator,
//% "category name"
qsTrId("category-name"),
maxCategoryNameLength)
}
}
}
StatusModalDivider {
topPadding: 8
bottomPadding: 8
}
Item {
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width - 32
height: 34
StatusBaseText {
//% "Channels"
text: qsTrId("channels")
anchors.bottom: parent.bottom
anchors.bottomMargin: 4
font.pixelSize: 15
color: Theme.palette.baseColor1
}
}
ListView {
id: communityChannelList
height: childrenRect.height
model: chatsModel.communities.activeCommunity.chats
anchors.left: parent.left
anchors.right: parent.right
delegate: StatusListItem {
Item {
id: channelsLabel
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width - 32
visible: popup.isEdit ?
model.categoryId === popup.categoryId || model.categoryId === "" :
model.categoryId === ""
height: 34
StatusBaseText {
//% "Channels"
text: qsTrId("channels")
anchors.bottom: parent.bottom
anchors.bottomMargin: 4
font.pixelSize: 15
color: Theme.palette.baseColor1
}
}
title: "#" + model.name
icon.isLetterIdenticon: true
icon.background.color: model.color
sensor.onClicked: channelItemCheckbox.checked = !channelItemCheckbox.checked
ListView {
id: communityChannelList
components: [
StatusCheckBox {
id: channelItemCheckbox
checked: popup.isEdit ? popup.channels.indexOf(model.id) > - 1 : false
onCheckedChanged: {
var idx = popup.channels.indexOf(model.id)
if(checked){
if(idx === -1){
popup.channels.push(model.id)
}
} else {
if(idx > -1){
popup.channels.splice(idx, 1);
anchors.top: channelsLabel.bottom
height: childrenRect.height
width: parent.width
model: chatsModel.communities.activeCommunity.chats
interactive: false
clip: true
delegate: StatusListItem {
anchors.horizontalCenter: parent.horizontalCenter
visible: popup.isEdit ?
model.categoryId === popup.categoryId || model.categoryId === "" :
model.categoryId === ""
height: visible ? implicitHeight : 0
title: "#" + model.name
icon.isLetterIdenticon: true
icon.background.color: model.color
sensor.onClicked: channelItemCheckbox.checked = !channelItemCheckbox.checked
components: [
StatusCheckBox {
id: channelItemCheckbox
checked: popup.isEdit ? popup.channels.indexOf(model.id) > - 1 : false
onCheckedChanged: {
var idx = popup.channels.indexOf(model.id)
if(checked){
if(idx === -1){
popup.channels.push(model.id)
}
} else {
if(idx > -1){
popup.channels.splice(idx, 1);
}
}
}
}
}
]
]
}
}
}
}
StatusModalDivider {
visible: deleteCategoryButton.visible
topPadding: 8
bottomPadding: 8
StatusModalDivider {
visible: deleteCategoryButton.visible
topPadding: 8
bottomPadding: 8
}
StatusListItem {
id: deleteCategoryButton
anchors.horizontalCenter: parent.horizontalCenter
visible: isEdit
//% "Delete category"
title: qsTrId("delete-category")
icon.name: "delete"
type: StatusListItem.Type.Danger
sensor.onClicked: {
openPopup(deleteCategoryConfirmationDialogComponent, {
//% "Delete %1 category"
title: qsTrId("delete--1-category").arg(popup.contentComponent.categoryName.text),
//% "Are you sure you want to delete %1 category? Channels inside the category wont be deleted."
confirmationText: qsTrId("are-you-sure-you-want-to-delete--1-category--channels-inside-the-category-won-t-be-deleted-").arg(popup.contentComponent.categoryName.text)
})
}
}
StatusListItem {
id: deleteCategoryButton
anchors.horizontalCenter: parent.horizontalCenter
visible: isEdit
Item {
height: 8
width: parent.width
}
//% "Delete category"
title: qsTrId("delete-category")
icon.name: "delete"
type: StatusListItem.Type.Danger
sensor.onClicked: {
openPopup(deleteCategoryConfirmationDialogComponent, {
//% "Delete %1 category"
title: qsTrId("delete--1-category").arg(popup.contentComponent.categoryName.text),
//% "Are you sure you want to delete %1 category? Channels inside the category wont be deleted."
confirmationText: qsTrId("are-you-sure-you-want-to-delete--1-category--channels-inside-the-category-won-t-be-deleted-").arg(popup.contentComponent.categoryName.text)
})
Component {
id: deleteCategoryConfirmationDialogComponent
ConfirmationDialog {
btnType: "warn"
height: 216
showCancelButton: true
onClosed: {
destroy()
}
}
StatusModalDivider {
topPadding: 8
}
Component {
id: deleteCategoryConfirmationDialogComponent
ConfirmationDialog {
btnType: "warn"
height: 216
showCancelButton: true
onClosed: {
destroy()
}
onCancelButtonClicked: {
close();
}
onConfirmButtonClicked: function(){
const error = chatsModel.communities.deleteCommunityCategory(chatsModel.communities.activeCommunity.id, popup.categoryId)
if (error) {
creatingError.text = error
return creatingError.open()
}
close();
popup.close()
onCancelButtonClicked: {
close();
}
onConfirmButtonClicked: function(){
const error = chatsModel.communities.deleteCommunityCategory(chatsModel.communities.activeCommunity.id, popup.categoryId)
if (error) {
creatingError.text = error
return creatingError.open()
}
close();
popup.close()
}
}
}