mirror of
https://github.com/status-im/status-desktop.git
synced 2025-02-17 00:56:39 +00:00
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:
parent
a406a24df5
commit
9f6a4f7834
@ -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 won’t 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 won’t 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user