From 17abf87bcf5b87ce366ad93f8b7fb6e99c81f3a2 Mon Sep 17 00:00:00 2001 From: Martynas Bagdonas Date: Thu, 25 Feb 2021 14:59:41 +0200 Subject: [PATCH] Improve notes list UI: - Show both sections even on search - Add new note creation popups with an option to create from annotations - Hide child notes section if no parent item --- .../zotero/components/itemPane/notesList.jsx | 20 ++-- chrome/content/zotero/contextPane.js | 99 ++++++++++++++----- chrome/content/zotero/zoteroPane.xul | 12 +++ chrome/locale/en-US/zotero/zotero.dtd | 5 + 4 files changed, 103 insertions(+), 33 deletions(-) diff --git a/chrome/content/zotero/components/itemPane/notesList.jsx b/chrome/content/zotero/components/itemPane/notesList.jsx index 07bde185da..f56389016f 100644 --- a/chrome/content/zotero/components/itemPane/notesList.jsx +++ b/chrome/content/zotero/components/itemPane/notesList.jsx @@ -51,11 +51,11 @@ const NoteRow = ({ title, body, date, onClick, parentItemType, parentTitle }) => ); }; -const NotesList = forwardRef(({ onClick, onNewChild, onNewStandalone }, ref) => { +const NotesList = forwardRef(({ onClick, onAddChildButtonDown, onAddStandaloneButtonDown }, ref) => { const [notes, setNotes] = useState([]); const [expanded, setExpanded] = useState(false); - const [searching, setSearching] = useState(false); - useImperativeHandle(ref, () => ({ setNotes, setExpanded, setSearching })); + const [hasParent, setHasParent] = useState(true); + useImperativeHandle(ref, () => ({ setNotes, setExpanded, setHasParent })); function handleClickMore() { setExpanded(true); @@ -65,27 +65,27 @@ const NotesList = forwardRef(({ onClick, onNewChild, onNewStandalone }, ref) => let allNotes = notes.filter(x => !x.isCurrentChild); return (
- {(!!childNotes.length || !searching) &&
+ {hasParent &&

{Zotero.getString('pane.context.itemNotes')}

- {!searching && } +
- {!childNotes.length && !searching &&
{Zotero.getString('pane.context.noNotes')}
} + {!childNotes.length &&
{Zotero.getString('pane.context.noNotes')}
} {childNotes.map(note => onClick(note.id)}/>)}
} - {(!!allNotes.length || !searching) &&
+

{Zotero.getString('pane.context.allNotes')}

- {!searching && } +
- {!allNotes.length && !searching &&
{Zotero.getString('pane.context.noNotes')}
} + {!allNotes.length &&
{Zotero.getString('pane.context.noNotes')}
} {(expanded ? allNotes : allNotes.slice(0, MAX_ALL_NOTES)).map(note => onClick(note.id)}/>)} {!expanded && allNotes.length > MAX_ALL_NOTES &&
{ Zotero.getString('general.numMore', Zotero.Utilities.numberFormat([allNotes.length - MAX_ALL_NOTES], 0)) }
} -
} +
); }); diff --git a/chrome/content/zotero/contextPane.js b/chrome/content/zotero/contextPane.js index fd29a0d6af..6e3c669356 100644 --- a/chrome/content/zotero/contextPane.js +++ b/chrome/content/zotero/contextPane.js @@ -369,14 +369,11 @@ var ZoteroContextPane = new function () { _panesDeck.append(_itemPaneDeck, _notesPaneDeck); } - - function _getCurrentParentItem() { + + function _getCurrentAttachment() { var reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID); if (reader) { - var attachment = Zotero.Items.get(reader.itemID); - if (attachment) { - return attachment.parentItem; - } + return Zotero.Items.get(reader.itemID); } } @@ -408,19 +405,42 @@ var ZoteroContextPane = new function () { var head = document.createElement('hbox'); head.style.display = 'flex'; + async function _createNoteFromAnnotations(child) { + var attachment = _getCurrentAttachment(); + if (!attachment) { + return; + } + var note = await Zotero.EditorInstance.createNoteFromAnnotations( + attachment.getAnnotations(), child && attachment.parentID + ); - function _createNote(parentID) { + _updateAddToNote(); + + input.value = ''; + _updateNotesList(); + + _setPinnedNote(note.id); + } + + function _createNote(child) { contextNode.setAttribute('selectedIndex', 1); var item = new Zotero.Item('note'); item.libraryID = libraryID; - if (parentID) { - item.parentID = parentID; + if (child) { + var attachment = _getCurrentAttachment(); + if (!attachment) { + return; + } + item.parentID = attachment.parentID; } editor.mode = 'edit'; editor.item = item; editor.parentItem = null; editor.focus(); _updateAddToNote(); + + input.value = ''; + _updateNotesList(); } var vbox = document.createElement('vbox'); @@ -498,11 +518,12 @@ var ZoteroContextPane = new function () { context.cachedNotes = notes; } - var readerParentItem = _getCurrentParentItem(); - notesListRef.current.setSearching(query.length); + var attachment = _getCurrentAttachment(); + var parentID = attachment && attachment.parentID; + notesListRef.current.setHasParent(!!parentID); notesListRef.current.setNotes(notes.map(note => ({ ...note, - isCurrentChild: readerParentItem && note.parentID == readerParentItem.id + isCurrentChild: parentID && note.parentID == parentID }))); } @@ -515,21 +536,50 @@ var ZoteroContextPane = new function () { update: Zotero.Utilities.throttle(_updateNotesList, 1000, { leading: false }), updateFromCache: () => _updateNotesList(true) }; + + function _handleAddChildNotePopupClick(event) { + switch (event.originalTarget.id) { + case 'context-pane-add-child-note': + _createNote(true); + break; + + case 'context-pane-add-child-note-from-annotations': + _createNoteFromAnnotations(true); + break; + + default: + } + } + + function _handleAddStandaloneNotePopupClick(event) { + switch (event.originalTarget.id) { + case 'context-pane-add-standalone-note': + _createNote(); + break; + + case 'context-pane-add-standalone-note-from-annotations': + _createNoteFromAnnotations(); + break; + + default: + } + } ReactDOM.render( { - _setPinnedNote(libraryID, id); + _setPinnedNote(id); }} - onNewChild={() => { - var parentItem = _getCurrentParentItem(); - if (parentItem) { - _createNote(parentItem.id); - } + onAddChildButtonDown={(event) => { + var popup = document.getElementById('context-pane-add-child-note-button-popup'); + popup.onclick = _handleAddChildNotePopupClick; + popup.openPopup(event.target, 'after_end'); }} - onNewStandalone={() => { - _createNote(); + onAddStandaloneButtonDown={(event) => { + var popup = document.getElementById('context-pane-add-standalone-note-button-popup'); + popup.onclick = _handleAddStandaloneNotePopupClick; + popup.openPopup(event.target, 'after_end'); }} />, listInner, @@ -570,10 +620,13 @@ var ZoteroContextPane = new function () { return true; } - function _setPinnedNote(libraryID, itemID) { - var editable = _isLibraryEditable(libraryID); - var context = _getNotesContext(libraryID); + function _setPinnedNote(itemID) { var item = Zotero.Items.get(itemID); + if (!item) { + return; + } + var editable = _isLibraryEditable(item.libraryID); + var context = _getNotesContext(item.libraryID); if (context) { var { editor, node } = context; node.setAttribute('selectedIndex', 1); diff --git a/chrome/content/zotero/zoteroPane.xul b/chrome/content/zotero/zoteroPane.xul index 58f5a2b603..b5e140694a 100644 --- a/chrome/content/zotero/zoteroPane.xul +++ b/chrome/content/zotero/zoteroPane.xul @@ -632,6 +632,18 @@ + + + + + + + + + + + + diff --git a/chrome/locale/en-US/zotero/zotero.dtd b/chrome/locale/en-US/zotero/zotero.dtd index 18c4e31a2f..f59cdd2128 100644 --- a/chrome/locale/en-US/zotero/zotero.dtd +++ b/chrome/locale/en-US/zotero/zotero.dtd @@ -329,3 +329,8 @@ + + + + +