refactor(communities): allow removing items from import file list
There was a requested design change where no longer wanted to have checkboxes to decide which files will be included for a discord import, but rather have an "X" button that enables users to remove items. This commit implements this refactor. In addition, it ensures that the already loaded discord categories and channels that have been extracted from validation, are kept in sync as well. Meaning, if a user removes a file from the file list, the corresponding channel will be removed as well. If there's not channel in a given category, the category will be removed as well. Closes #8125 #8126
This commit is contained in:
parent
15891295e9
commit
8d90204e0a
|
@ -73,6 +73,19 @@ QtObject:
|
|||
return i
|
||||
return -1
|
||||
|
||||
proc removeItem*(self: DiscordCategoriesModel, id: string) =
|
||||
let idx = self.findIndexById(id)
|
||||
if(idx == -1):
|
||||
return
|
||||
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
|
||||
self.beginRemoveRows(parentModelIndex, idx, idx)
|
||||
self.items.delete(idx)
|
||||
self.endRemoveRows()
|
||||
self.countChanged()
|
||||
|
||||
proc addItem*(self: DiscordCategoriesModel, item: DiscordCategoryItem) =
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, Tables
|
||||
import NimQml, Tables, strutils
|
||||
import discord_channel_item
|
||||
|
||||
type
|
||||
|
@ -116,6 +116,13 @@ QtObject:
|
|||
return i
|
||||
return -1
|
||||
|
||||
proc findIndicesByFilePath(self: DiscordChannelsModel, filePath: string): seq[int] =
|
||||
var indices: seq[int] = @[]
|
||||
for i in 0 ..< self.items.len:
|
||||
if(self.items[i].getFilePath() == filePath):
|
||||
indices.add(i)
|
||||
return indices
|
||||
|
||||
proc getItem*(self: DiscordChannelsModel, id: string): DiscordChannelItem =
|
||||
for i in 0 ..< self.items.len:
|
||||
if(self.items[i].getId() == id):
|
||||
|
@ -129,6 +136,12 @@ QtObject:
|
|||
break
|
||||
return allUnselected
|
||||
|
||||
proc hasItemsWithCategoryId*(self: DiscordChannelsModel, categoryId: string): bool =
|
||||
for i in 0 ..< self.items.len:
|
||||
if(self.items[i].getCategoryId() == categoryId):
|
||||
return true
|
||||
return false
|
||||
|
||||
proc getHasSelectedItems*(self: DiscordChannelsModel): bool {.slot.} =
|
||||
for i in 0 ..< self.items.len:
|
||||
if self.items[i].getSelected():
|
||||
|
@ -139,6 +152,18 @@ QtObject:
|
|||
read = getHasSelectedItems
|
||||
notify = hasSelectedItemsChanged
|
||||
|
||||
proc removeItemsByFilePath*(self: DiscordChannelsModel, filePath: string) =
|
||||
let indices = self.findIndicesByFilePath(filePath)
|
||||
for i in 0 ..< indices.len:
|
||||
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
|
||||
self.beginRemoveRows(parentModelIndex, indices[i], indices[i])
|
||||
self.items.delete(indices[i])
|
||||
self.endRemoveRows()
|
||||
self.countChanged()
|
||||
|
||||
proc addItem*(self: DiscordChannelsModel, item: DiscordChannelItem) =
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
|
@ -163,6 +188,12 @@ QtObject:
|
|||
self.dataChanged(index, index, @[ModelRole.Selected.int])
|
||||
self.hasSelectedItemsChanged()
|
||||
|
||||
proc getChannelCategoryIdByFilePath*(self: DiscordChannelsModel, filePath: string): string =
|
||||
for i in 0 ..< self.items.len:
|
||||
if(self.items[i].getFilePath() == filePath):
|
||||
return self.items[i].getCategoryId()
|
||||
return ""
|
||||
|
||||
proc getSelectedItems*(self: DiscordChannelsModel): seq[DiscordChannelItem] =
|
||||
for i in 0 ..< self.items.len:
|
||||
if self.items[i].getSelected():
|
||||
|
|
|
@ -132,6 +132,19 @@ QtObject:
|
|||
return i
|
||||
return -1
|
||||
|
||||
proc removeItem*(self: DiscordFileListModel, filePath: string) =
|
||||
let idx = self.findIndexByFilePath(filePath)
|
||||
if(idx == -1):
|
||||
return
|
||||
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
|
||||
self.beginRemoveRows(parentModelIndex, idx, idx)
|
||||
self.items.delete(idx)
|
||||
self.endRemoveRows()
|
||||
self.countChanged()
|
||||
|
||||
proc addItem*(self: DiscordFileListModel, item: DiscordFileItem) =
|
||||
let parentModelIndex = newQModelIndex()
|
||||
defer: parentModelIndex.delete
|
||||
|
|
|
@ -462,6 +462,20 @@ QtObject:
|
|||
return false
|
||||
return sectionItem.hasMember(pubKey)
|
||||
|
||||
proc removeFileListItem*(self: View, filePath: string) {.slot.} =
|
||||
var path = filePath
|
||||
if path.startsWith("file://"):
|
||||
path = replace(path, "file://", "")
|
||||
|
||||
let categoryId = self.discordChannelsModel.getChannelCategoryIdByFilePath(path)
|
||||
|
||||
# file list still uses full path, so relying on `filePath` here
|
||||
self.discordFileListModel.removeItem(filePath)
|
||||
self.discordChannelsModel.removeItemsByFilePath(path)
|
||||
|
||||
if categoryId != "" and not self.discordChannelsModel.hasItemsWithCategoryId(categoryId):
|
||||
self.discordCategoriesModel.removeItem(categoryId)
|
||||
|
||||
proc setFileListItems*(self: View, filePaths: string) {.slot.} =
|
||||
let filePaths = filePaths.split(',')
|
||||
var fileItems: seq[DiscordFileItem] = @[]
|
||||
|
|
|
@ -200,18 +200,35 @@ StatusStackModal {
|
|||
model: fileListView.fileListModel
|
||||
delegate: ColumnLayout {
|
||||
width: ListView.view.width
|
||||
StatusCheckBox {
|
||||
id: fileCheckBox
|
||||
RowLayout {
|
||||
spacing: 20
|
||||
Layout.fillWidth: true
|
||||
text: model.filePath
|
||||
font.pixelSize: 13
|
||||
checked: model.selected
|
||||
enabled: model.errorMessage === "" // TODO distinguish between error/warning
|
||||
onToggled: model.selected = checked
|
||||
Layout.topMargin: 8
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
text: model.filePath
|
||||
font.pixelSize: 13
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.WordWrap
|
||||
maximumLineCount: 2
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: removeButton
|
||||
Layout.preferredWidth: 32
|
||||
Layout.preferredHeight: 32
|
||||
type: StatusFlatRoundButton.Type.Secondary
|
||||
icon.name: "close"
|
||||
icon.color: Theme.palette.directColor1
|
||||
icon.width: 24
|
||||
icon.height: 24
|
||||
onClicked: root.store.removeFileListItem(model.filePath)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: fileCheckBox.leftPadding + fileCheckBox.spacing + fileCheckBox.indicator.width
|
||||
text: "%1 %2".arg("⚠").arg(model.errorMessage)
|
||||
visible: model.errorMessage
|
||||
font.pixelSize: 13
|
||||
|
|
|
@ -93,6 +93,9 @@ QtObject {
|
|||
root.communitiesModuleInst.navigateToCommunity(communityId)
|
||||
}
|
||||
|
||||
function removeFileListItem(filePath) {
|
||||
root.communitiesModuleInst.removeFileListItem(filePath)
|
||||
}
|
||||
function setFileListItems(filePaths) {
|
||||
root.communitiesModuleInst.setFileListItems(filePaths)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue