feat: Re-enabled multiple selection on mobile, with improved UI (#2609)
This commit is contained in:
@@ -101,6 +101,8 @@ export class ItemListController
|
||||
selectedUuids: Set<UuidString> = observable(new Set<UuidString>())
|
||||
selectedItems: Record<UuidString, ListableContentItem> = {}
|
||||
|
||||
isMultipleSelectionMode = false
|
||||
|
||||
override deinit() {
|
||||
super.deinit()
|
||||
;(this.noteFilterText as unknown) = undefined
|
||||
@@ -169,6 +171,10 @@ export class ItemListController
|
||||
setSelectedItems: action,
|
||||
|
||||
hydrateFromPersistedValue: action,
|
||||
|
||||
isMultipleSelectionMode: observable,
|
||||
enableMultipleSelectionMode: action,
|
||||
cancelMultipleSelection: action,
|
||||
})
|
||||
|
||||
eventBus.addEventHandler(this, CrossControllerEvent.TagChanged)
|
||||
@@ -257,6 +263,17 @@ export class ItemListController
|
||||
),
|
||||
)
|
||||
|
||||
this.disposers.push(
|
||||
reaction(
|
||||
() => this.selectedItemsCount,
|
||||
() => {
|
||||
if (this.selectedItemsCount === 0) {
|
||||
this.cancelMultipleSelection()
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
window.onresize = () => {
|
||||
this.resetPagination(true)
|
||||
}
|
||||
@@ -1079,6 +1096,9 @@ export class ItemListController
|
||||
runInAction(() => {
|
||||
this.setSelectedUuids(this.selectedUuids.add(item.uuid))
|
||||
this.lastSelectedItem = item
|
||||
if (this.selectedItemsCount > 1 && !this.isMultipleSelectionMode) {
|
||||
this.enableMultipleSelectionMode()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1086,6 +1106,8 @@ export class ItemListController
|
||||
cancelMultipleSelection = () => {
|
||||
this.keyboardService.cancelAllKeyboardModifiers()
|
||||
|
||||
this.isMultipleSelectionMode = false
|
||||
|
||||
const firstSelectedItem = this.firstSelectedItem
|
||||
|
||||
if (firstSelectedItem) {
|
||||
@@ -1095,7 +1117,7 @@ export class ItemListController
|
||||
}
|
||||
}
|
||||
|
||||
private replaceSelection = (item: ListableContentItem): void => {
|
||||
replaceSelection = (item: ListableContentItem): void => {
|
||||
this.deselectAll()
|
||||
runInAction(() => this.setSelectedUuids(this.selectedUuids.add(item.uuid)))
|
||||
|
||||
@@ -1103,10 +1125,11 @@ export class ItemListController
|
||||
}
|
||||
|
||||
selectAll = () => {
|
||||
void this.selectItemsRange({
|
||||
startingIndex: 0,
|
||||
endingIndex: this.listLength - 1,
|
||||
})
|
||||
const allItems = this.items.filter((item) => !item.protected)
|
||||
const lastItem = allItems[allItems.length - 1]
|
||||
this.setSelectedUuids(new Set(Uuids(allItems)))
|
||||
this.lastSelectedItem = lastItem
|
||||
this.enableMultipleSelectionMode()
|
||||
}
|
||||
|
||||
deselectAll = (): void => {
|
||||
@@ -1136,6 +1159,10 @@ export class ItemListController
|
||||
}
|
||||
}
|
||||
|
||||
enableMultipleSelectionMode = () => {
|
||||
this.isMultipleSelectionMode = true
|
||||
}
|
||||
|
||||
selectItem = async (
|
||||
uuid: UuidString,
|
||||
userTriggered?: boolean,
|
||||
@@ -1152,14 +1179,13 @@ export class ItemListController
|
||||
|
||||
log(LoggingDomain.Selection, 'Select item', item.uuid)
|
||||
|
||||
const supportsMultipleSelection = this.options.allowMultipleSelection
|
||||
const hasMeta = this.keyboardService.activeModifiers.has(KeyboardModifier.Meta)
|
||||
const hasCtrl = this.keyboardService.activeModifiers.has(KeyboardModifier.Ctrl)
|
||||
const hasShift = this.keyboardService.activeModifiers.has(KeyboardModifier.Shift)
|
||||
const hasMoreThanOneSelected = this.selectedItemsCount > 1
|
||||
const isAuthorizedForAccess = await this.protections.authorizeItemAccess(item)
|
||||
|
||||
if (supportsMultipleSelection && userTriggered && (hasMeta || hasCtrl)) {
|
||||
if (userTriggered && hasShift) {
|
||||
await this.selectItemsRange({ selectedItem: item })
|
||||
} else if (userTriggered && this.isMultipleSelectionMode) {
|
||||
if (this.selectedUuids.has(uuid) && hasMoreThanOneSelected) {
|
||||
this.removeSelectedItem(uuid)
|
||||
} else if (isAuthorizedForAccess) {
|
||||
@@ -1167,17 +1193,17 @@ export class ItemListController
|
||||
this.setSelectedUuids(this.selectedUuids)
|
||||
this.lastSelectedItem = item
|
||||
}
|
||||
} else if (supportsMultipleSelection && userTriggered && hasShift) {
|
||||
await this.selectItemsRange({ selectedItem: item })
|
||||
if (this.selectedItemsCount === 1) {
|
||||
this.cancelMultipleSelection()
|
||||
}
|
||||
} else {
|
||||
const shouldSelectNote = hasMoreThanOneSelected || !this.selectedUuids.has(uuid)
|
||||
if (shouldSelectNote && isAuthorizedForAccess) {
|
||||
this.replaceSelection(item)
|
||||
await this.openSingleSelectedItem({ userTriggered: userTriggered ?? false })
|
||||
}
|
||||
}
|
||||
|
||||
await this.openSingleSelectedItem({ userTriggered: userTriggered ?? false })
|
||||
|
||||
return {
|
||||
didSelect: this.selectedUuids.has(uuid),
|
||||
}
|
||||
|
||||
@@ -293,6 +293,17 @@ export class NotesController
|
||||
})
|
||||
}
|
||||
|
||||
async toggleArchiveSelectedNotes(): Promise<void> {
|
||||
const notes = this.selectedNotes
|
||||
const archived = notes.some((note) => note.archived)
|
||||
|
||||
if (!archived) {
|
||||
await this.setArchiveSelectedNotes(true)
|
||||
} else {
|
||||
await this.setArchiveSelectedNotes(false)
|
||||
}
|
||||
}
|
||||
|
||||
async setProtectSelectedNotes(protect: boolean): Promise<void> {
|
||||
const selectedNotes = this.getSelectedNotesList()
|
||||
if (protect) {
|
||||
|
||||
Reference in New Issue
Block a user