import { Numbers } from "polar-shared/src/util/Numbers" ; import { Arrays } from "polar-shared/src/util/Arrays" ; import { SetArrays } from "polar-shared/src/util/SetArrays" ; import { IDStr } from "polar-shared/src/util/Strings" ; import { IMouseEvent } from "./MUIContextMenu2" ; /**
 * The type of event that triggered the row selection.  Either a normal click, a context menu click (right click) or
 * a checkbox for selecting multiple.
 */ export type SelectRowType = 'click' | 'context' | 'checkbox' ; interface IDType { readonly id : IDStr ; } export type SelectedRows = ReadonlyArray < IDStr > ; /**
 * Code to allow the user to select multiple items where with an array of items
 * which have IDs and a viewPage of items that have IDs.
 */ export namespace SelectionEvents2 { export function selectRow < T extends IDType > ( viewID , currentlySelected , view , event , type ) { type SelectionStrategy = 'one' | 'range' | 'toggle' | 'none' ; const computeStrategy = ( ) : SelectionStrategy => { if ( type === 'checkbox' ) { return 'toggle' ; } if ( type === 'click' ) { if ( event . getModifierState ( "Shift" ) ) { return 'range' ; } if ( event . getModifierState ( "Control" ) || event . getModifierState ( "Meta" ) ) { return 'toggle' ; } } if ( type === 'context' ) { if ( currentlySelected . includes ( viewID ) ) { return 'none' ; } } return 'one' ; } ; const computeStrategy2 = ( ) : SelectionStrategy => { if ( type === 'checkbox' ) { return 'toggle' ; } if ( type === 'click' ) { if ( event . getModifierState ( "Shift" ) ) { return 'range' ; } if ( event . getModifierState ( "Control" ) || event . getModifierState ( "Meta" ) ) { return 'toggle' ; } } if ( type === 'context' ) { if ( currentlySelected . includes ( viewID ) ) { return 'none' ; } } return 'one' ; } ; function computeSelectedIndexes ( ) { const viewPageIDs = view . map ( current => current . id ) ; return currentlySelected . map ( current => viewPageIDs . indexOf ( current ) ) ; } const doStrategyRange = ( ) : SelectedRows => { let min = 0 ; let max = 0 ; const selected = computeSelectedIndexes ( ) ; const selectedIdx = view . map ( current => current . id ) . indexOf ( viewID ) ; if ( selected . length > 0 ) { const sorted = [ ... selected ] . sort ( ( a , b ) => a - b ) ; min = Arrays . first ( sorted ) ! ; max = Arrays . last ( sorted ) ! ; } const rangeMin = Math . min ( min , selectedIdx ) ; const rangeMax = Math . max ( max , selectedIdx ) ; const viewPagePointers = [ ... Numbers . range ( rangeMin , rangeMax ) ] ; return viewPagePointers . map ( ptr => view [ ptr ] . id ) ; } ; const doStrategyToggle = ( ) : SelectedRows => { const selected = computeSelectedIndexes ( ) ; const selectedIdx = view . map ( current => current . id ) . indexOf ( viewID ) ; function computeViewPagePointers ( ) { if ( selected . includes ( selectedIdx ) ) { return SetArrays . difference ( selected , [ selectedIdx ] ) ; } else { return SetArrays . union ( selected , [ selectedIdx ] ) ; } } const viewPagePointers = computeViewPagePointers ( ) ; return viewPagePointers . map ( ptr => view [ ptr ] . id ) ; } ; const doStrategyOne = ( ) : SelectedRows => { return [ viewID ] ; } ; const doStrategy = ( ) : SelectedRows => { const strategy = computeStrategy ( ) ; switch ( strategy ) { case "one" : return doStrategyOne ( ) ; case "range" : return doStrategyRange ( ) ; case "toggle" : return doStrategyToggle ( ) ; case "none" : return currentlySelected ; } } ; return doStrategy ( ) ; } }