import { h } from 'preact'; import { useState, useEffect, useRef } from 'preact/hooks'; import { log } from '../utils'; import { trackEvent } from '../analytics'; import { ItemTile } from './ItemTile'; import { Trans, t } from '@lingui/macro'; import { I18n } from '@lingui/react'; export default function SavedItemPane({ itemsMap, isOpen, closeHandler, onItemSelect, onItemRemove, onItemFork, onExport, mergeImportedItems }) { const [items, setItems] = useState([]); const [filteredItems, setFilteredItems] = useState([]); const searchInputRef = useRef(); useEffect(() => { if (!itemsMap) return; const newItems = Object.values(itemsMap); newItems.sort(function (a, b) { return b.updatedOn - a.updatedOn; }); setItems(newItems); setFilteredItems(newItems); }, [itemsMap]); useEffect(() => { // Opening if (isOpen) { searchInputRef.current.value = ''; searchInputRef.current.focus(); } // Closing if (!isOpen) { setFilteredItems([]); } }, [isOpen]); function onCloseIntent() { closeHandler(); } function itemClickHandler(item) { onItemSelect(item); } function itemRemoveBtnClickHandler(item, e) { e.stopPropagation(); onItemRemove(item); } function itemForkBtnClickHandler(item, e) { e.stopPropagation(); onItemFork(item); } function keyDownHandler(event) { if (!isOpen) { return; } const isCtrlOrMetaPressed = event.ctrlKey || event.metaKey; const isForkKeyPressed = isCtrlOrMetaPressed && event.keyCode === 70; const isDownKeyPressed = event.keyCode === 40; const isUpKeyPressed = event.keyCode === 38; const isEnterKeyPressed = event.keyCode === 13; const selectedItemElement = $('.js-saved-item-tile.selected'); const havePaneItems = $all('.js-saved-item-tile').length !== 0; if ((isDownKeyPressed || isUpKeyPressed) && havePaneItems) { const method = isDownKeyPressed ? 'nextUntil' : 'previousUntil'; if (selectedItemElement) { selectedItemElement.classList.remove('selected'); selectedItemElement[method]( '.js-saved-item-tile:not(.hide)' ).classList.add('selected'); } else { $('.js-saved-item-tile:not(.hide)').classList.add('selected'); } $('.js-saved-item-tile.selected').scrollIntoView(false); } if (isEnterKeyPressed && selectedItemElement) { const item = itemsMap[selectedItemElement.dataset.itemId]; onItemSelect(item); trackEvent('ui', 'openItemKeyboardShortcut'); } // Fork shortcut inside saved creations panel with Ctrl/⌘ + F if (isForkKeyPressed) { event.preventDefault(); const item = itemsMap[selectedItemElement.dataset.itemId]; itemForkBtnClickHandler(item); trackEvent('ui', 'forkKeyboardShortcut'); } } function importFileChangeHandler(e) { var file = e.target.files[0]; var reader = new FileReader(); reader.addEventListener('load', progressEvent => { var items; try { items = JSON.parse(progressEvent.target.result); log(items); mergeImportedItems(items); } catch (exception) { log(exception); alert( i18n._( t`'Oops! Selected file is corrupted. Please select a file that was generated by clicking the "Export" button.` ) ); } }); reader.readAsText(file, 'utf-8'); } function importBtnClickHandler(e) { var input = document.createElement('input'); input.type = 'file'; input.style.display = 'none'; input.accept = 'accept="application/json'; document.body.appendChild(input); input.addEventListener('change', importFileChangeHandler); input.click(); trackEvent('ui', 'importBtnClicked'); e.preventDefault(); } function searchInputHandler(e) { const text = e.target.value.toLowerCase().trim(); if (!text) { setFilteredItems(items); } else { setFilteredItems( items.filter(item => item.title.toLowerCase().indexOf(text) !== -1) ); } trackEvent('ui', 'searchInputType'); } return ( {({ i18n }) => (

My Library ({filteredItems.length})

e.preventDefault()}>
{!filteredItems.length && items.length ? (
No match found.
) : null} {filteredItems.map(item => ( itemClickHandler(item)} onForkBtnClick={e => itemForkBtnClickHandler(item, e)} onRemoveBtnClick={e => itemRemoveBtnClickHandler(item, e)} /> ))} {!items.length ? (

Nothing saved here.

) : null}
)}
); }