From b45b040ceadbfea0949ed3f39ee45dd7ad809ef3 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Thu, 8 Jun 2023 13:56:11 +0800 Subject: [PATCH] Keyboard controls for multi select --- .../templates/homeFeed/HomeFeedContainer.tsx | 44 +++++++++++++++---- .../templates/homeFeed/LibraryHeader.tsx | 12 ++--- .../keyboardShortcuts/navigationShortcuts.ts | 16 +++++++ 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx index 524795b92..a709bbc8c 100644 --- a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx +++ b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx @@ -331,6 +331,23 @@ export function HomeFeedContainer(): JSX.Element { return labelsTarget || linkToEdit || linkToRemove || linkToUnsubscribe }, [labelsTarget, linkToEdit, linkToRemove, linkToUnsubscribe]) + const [checkedItems, setCheckedItems] = useState([]) + const [multiSelectMode, setMultiSelectMode] = useState('off') + + const selectActiveArticle = useCallback(() => { + console.log('selecting article: ', activeItem) + if (activeItem) { + if (multiSelectMode === 'off') { + console.log('setting ') + setMultiSelectMode('none') + } + const itemId = activeItem.node.id + const isChecked = itemIsChecked(itemId) + console.log('setting is checked: ', isChecked, itemId) + setIsChecked(itemId, !isChecked) + } + }, [activeItem, multiSelectMode, checkedItems]) + useKeyboardShortcuts( libraryListCommands((action) => { const columnCount = (container: HTMLDivElement) => { @@ -348,7 +365,16 @@ export function HomeFeedContainer(): JSX.Element { switch (action) { case 'openArticle': - handleCardAction('showDetail', activeItem) + if (multiSelectMode !== 'off' && activeItem) { + const itemId = activeItem.node.id + const isChecked = itemIsChecked(itemId) + setIsChecked(itemId, !isChecked) + } else { + handleCardAction('showDetail', activeItem) + } + break + case 'selectArticle': + selectActiveArticle() break case 'openOriginalArticle': handleCardAction('showOriginal', activeItem) @@ -435,6 +461,11 @@ export function HomeFeedContainer(): JSX.Element { case 'sortAscending': setQueryInputs({ ...queryInputs, sortDescending: false }) break + case 'beginMultiSelect': + if (multiSelectMode == 'off') { + setMultiSelectMode('none') + } + break } }) ) @@ -522,23 +553,22 @@ export function HomeFeedContainer(): JSX.Element { ) useFetchMore(handleFetchMore) - const [checkedItems, setCheckedItems] = useState([]) - const [multiSelectMode, setMultiSelectMode] = useState('off') - const setIsChecked = useCallback( (itemId: string, set: boolean) => { + console.log('setting is checked with list: ', checkedItems) if (set && checkedItems.indexOf(itemId) === -1) { checkedItems.push(itemId) setCheckedItems([...checkedItems]) } else if (!set && checkedItems.indexOf(itemId) !== -1) { - setCheckedItems(checkedItems.splice(checkedItems.indexOf(itemId), 1)) + checkedItems.splice(checkedItems.indexOf(itemId)) + setCheckedItems([...checkedItems]) } }, [checkedItems] ) useEffect(() => { - console.log('switching on multiselect mode: ', multiSelectMode) + console.log(' -- multiselect mode: ', multiSelectMode) switch (multiSelectMode) { case 'off': case 'none': @@ -687,8 +717,6 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element { const [showFilterMenu, setShowFilterMenu] = useState(false) - console.log('props.multiSelectMode: ', props.multiSelectMode) - return ( { - if (window.scrollY > 5 || props.multiSelectMode != 'off') { - setShowBackground(true) - } - }) + setShowBackground(window.scrollY > 5 || props.multiSelectMode !== 'off') + }, [props.multiSelectMode]) useScrollWatcher((changeset: ScrollOffsetChangeset) => { - setShowBackground(window.scrollY > 5) + setShowBackground(window.scrollY > 5 || props.multiSelectMode !== 'off') }, 0) return ( diff --git a/packages/web/lib/keyboardShortcuts/navigationShortcuts.ts b/packages/web/lib/keyboardShortcuts/navigationShortcuts.ts index 2c4bd0bab..f01044200 100644 --- a/packages/web/lib/keyboardShortcuts/navigationShortcuts.ts +++ b/packages/web/lib/keyboardShortcuts/navigationShortcuts.ts @@ -74,6 +74,7 @@ export function primaryCommands( type LibraryListKeyboardAction = | 'openArticle' + | 'selectArticle' | 'openOriginalArticle' | 'moveFocusToNextListItem' | 'moveFocusToPreviousListItem' @@ -88,6 +89,7 @@ type LibraryListKeyboardAction = | 'shareItem' | 'showAddLinkModal' | 'showEditLabelsModal' + | 'beginMultiSelect' export function libraryListCommands( actionHandler: (action: LibraryListKeyboardAction) => void @@ -99,6 +101,14 @@ export function libraryListCommands( shortcutKeyDescription: 'enter/return', callback: () => actionHandler('openArticle'), }, + { + shortcutKeys: ['x'], + actionDescription: 'Select article', + shortcutKeyDescription: 'x', + callback: () => { + actionHandler('selectArticle') + }, + }, { shortcutKeys: ['o'], actionDescription: 'Open original article', @@ -123,6 +133,12 @@ export function libraryListCommands( shortcutKeyDescription: 'k or left arrow', callback: () => actionHandler('moveFocusToPreviousListItem'), }, + { + shortcutKeys: ['m', 's'], + actionDescription: 'Begin multi select', + shortcutKeyDescription: 'm then s', + callback: () => actionHandler('beginMultiSelect'), + }, // { // shortcutKeys: ['e'], // actionDescription: 'Archive item',