diff --git a/chrome/content/zotero/components/itemPane/notesList.jsx b/chrome/content/zotero/components/itemPane/notesList.jsx
index 1c2234e067..a16d330cda 100644
--- a/chrome/content/zotero/components/itemPane/notesList.jsx
+++ b/chrome/content/zotero/components/itemPane/notesList.jsx
@@ -52,9 +52,18 @@ const NoteRow = ({ title, body, date, onClick, parentItemType, parentTitle }) =>
const NotesList = forwardRef(({ onClick }, ref) => {
const [notes, setNotes] = useState([]);
useImperativeHandle(ref, () => ({ setNotes }));
+ let currentChildNotes = notes.filter(x => x.isCurrentChild);
+ let allNotes = notes.filter(x => !x.isCurrentChild);
return (
- {notes.map(note => onClick(note.id)}/>)}
+
+ {!!currentChildNotes.length && {Zotero.getString('pane.context.itemNotes')}
}
+ {currentChildNotes.map(note => onClick(note.id)}/>)}
+
+
+ {!!allNotes && {Zotero.getString('pane.context.allNotes')}
}
+ {allNotes.map(note => onClick(note.id)}/>)}
+
);
});
diff --git a/chrome/content/zotero/contextPane.js b/chrome/content/zotero/contextPane.js
index 2194e6b346..c1fadb2580 100644
--- a/chrome/content/zotero/contextPane.js
+++ b/chrome/content/zotero/contextPane.js
@@ -168,6 +168,11 @@ var ZoteroContextPane = new function () {
await reader._initPromise;
_tabCover.hidden = true;
})();
+
+ var attachment = Zotero.Items.get(reader.itemID);
+ _selectNotesContext(attachment.libraryID);
+ var notesContext = _getNotesContext(attachment.libraryID);
+ notesContext.updateFromCache();
}
_contextPaneSplitter.setAttribute('hidden', false);
@@ -177,10 +182,6 @@ var ZoteroContextPane = new function () {
_splitButton.classList.remove('hidden');
}
- var context = _itemContexts.find(x => x.tabID == ids[0]);
- if (context) {
- _selectNotesContext(context.libraryID);
- }
_selectItemContext(ids[0]);
_update();
}
@@ -365,6 +366,16 @@ var ZoteroContextPane = new function () {
_panesDeck.append(_itemPaneDeck, _notesPaneDeck);
}
+
+ function _getCurrentParentItem() {
+ var reader = Zotero.Reader.getByTabID(Zotero_Tabs.selectedID);
+ if (reader) {
+ var attachment = Zotero.Items.get(reader.itemID);
+ if (attachment) {
+ return attachment.parentItem;
+ }
+ }
+ }
function _addNotesContext(libraryID) {
var list = document.createElement('vbox');
@@ -372,10 +383,12 @@ var ZoteroContextPane = new function () {
list.className = 'zotero-context-notes-list';
var noteContainer = document.createElement('vbox');
+ var title = document.createElement('vbox');
+ title.className = 'zotero-context-pane-editor-parent-line';
var editor = document.createElement('zoteronoteeditor');
editor.className = 'zotero-context-pane-pinned-note';
editor.setAttribute('flex', 1);
- noteContainer.appendChild(editor);
+ noteContainer.append(title, editor);
let contextNode = document.createElement('deck');
contextNode.append(list, noteContainer);
@@ -404,7 +417,10 @@ var ZoteroContextPane = new function () {
break;
case 'context-pane-new-item-note':
- // TODO: Get the parent item
+ var parentItem = _getCurrentParentItem();
+ if (!parentItem) {
+ return;
+ }
parentID = parentItem.id;
break;
@@ -456,53 +472,71 @@ var ZoteroContextPane = new function () {
var notesListRef = React.createRef();
- async function _updateNotesList(reset) {
- if (reset) {
- input.value = '';
- contextNode.setAttribute('selectedIndex', 0);
+ async function _updateNotesList(useCached) {
+ var notes;
+ if (useCached && context.cachedNotes.length) {
+ notes = context.cachedNotes;
}
- var query = input.value;
-
- await Zotero.Schema.schemaUpdatePromise;
- var s = new Zotero.Search();
- s.addCondition('libraryID', 'is', libraryID);
- s.addCondition('itemType', 'is', 'note');
- if (query) {
- let parts = Zotero.SearchConditions.parseSearchString(query);
- for (let part of parts) {
- s.addCondition('note', 'contains', part.text);
+ else {
+ var query = input.value;
+ await Zotero.Schema.schemaUpdatePromise;
+ var s = new Zotero.Search();
+ s.addCondition('libraryID', 'is', libraryID);
+ s.addCondition('itemType', 'is', 'note');
+ if (query) {
+ let parts = Zotero.SearchConditions.parseSearchString(query);
+ for (let part of parts) {
+ s.addCondition('note', 'contains', part.text);
+ }
}
+ notes = await s.search();
+ notes = Zotero.Items.get(notes);
+ notes.sort((a, b) => {
+ a = a.getField('dateModified');
+ b = b.getField('dateModified');
+ return b.localeCompare(a);
+ });
+
+ notes = notes.map(note => {
+ var parentItem = note.parentItem;
+ var text = note.note;
+ text = Zotero.Utilities.unescapeHTML(text);
+ text = text.trim();
+ text = text.slice(0, 500);
+ var parts = text.split('\n').map(x => x.trim()).filter(x => x.length);
+ var title = parts[0] && parts[0].slice(0, Zotero.Notes.MAX_TITLE_LENGTH);
+ return {
+ id: note.id,
+ title: title || Zotero.getString('pane.item.notes.untitled'),
+ body: parts[1] || '',
+ date: (new Date(note.dateModified).toLocaleDateString(Zotero.locale)),
+ parentID: note.parentID,
+ parentItemType: parentItem && parentItem.itemType,
+ parentTitle: parentItem && parentItem.getDisplayTitle()
+ };
+ });
+ context.cachedNotes = notes;
}
- var notes = await s.search();
- notes = Zotero.Items.get(notes);
- notes.sort((a, b) => {
- a = a.getField('dateModified');
- b = b.getField('dateModified');
- return b.localeCompare(a);
- });
- notesListRef.current.setNotes(notes.map(note => {
- var parentItem = note.parentItem;
- var text = note.note;
- text = Zotero.Utilities.unescapeHTML(text);
- text = text.trim();
- text = text.slice(0, 500);
- var parts = text.split('\n').map(x => x.trim()).filter(x => x.length);
- var title = parts[0] && parts[0].slice(0, Zotero.Notes.MAX_TITLE_LENGTH);
- return {
- id: note.id,
- title: title || Zotero.getString('pane.item.notes.untitled'),
- body: parts[1] || '',
- date: (new Date(note.dateModified).toLocaleDateString(Zotero.locale)),
- parentItemType: parentItem && parentItem.itemType,
- parentTitle: parentItem && parentItem.getDisplayTitle()
- };
- }));
+ var readerParentItem = _getCurrentParentItem();
+ notesListRef.current.setNotes(notes.map(note => ({
+ ...note,
+ isCurrentChild: readerParentItem && note.parentID == readerParentItem.id
+ })));
var c = notes.length;
label.value = Zotero.getString('pane.item.notes.count', c, c);
}
+ var context = {
+ libraryID,
+ node: contextNode,
+ editor,
+ cachedNotes: [],
+ update: Zotero.Utilities.throttle(_updateNotesList, 1000, { leading: false }),
+ updateFromCache: () => _updateNotesList(true)
+ };
+
ReactDOM.render(
{
- onClick(id);
- });
- box.appendChild(icon);
- box.appendChild(label);
- var row = document.createElement('row');
- row.appendChild(box);
- if (editable) {
- var removeButton = document.createElement('label');
- removeButton.setAttribute('value', '-');
- removeButton.setAttribute('class', 'zotero-clicky zotero-clicky-minus');
- removeButton.addEventListener('click', function () {
- onDelete(id);
- });
- row.appendChild(removeButton);
+ node.querySelector('.zotero-context-pane-editor-parent-line').innerHTML = '';
+ var parentItem = item.parentItem;
+ if (parentItem) {
+ var container = document.createElementNS(HTML_NS, 'div');
+ var img = document.createElementNS(HTML_NS, 'img');
+ img.src = Zotero.ItemTypes.getImageSrc(parentItem.itemType);
+ img.className = 'parent-item-type';
+ var title = document.createElementNS(HTML_NS, 'div');
+ title.append(parentItem.getDisplayTitle());
+ title.className = 'parent-title';
+ container.append(img, title);
+ node.querySelector('.zotero-context-pane-editor-parent-line').append(container);
}
-
- list.appendChild(row);
+ _updateAddToNote();
}
}
diff --git a/chrome/content/zotero/xpcom/reader.js b/chrome/content/zotero/xpcom/reader.js
index 6f7eb51f17..7bb1801322 100644
--- a/chrome/content/zotero/xpcom/reader.js
+++ b/chrome/content/zotero/xpcom/reader.js
@@ -41,9 +41,6 @@ class ReaderInstance {
}
async open({ itemID, state, location }) {
- if (itemID === this._itemID) {
- return false;
- }
let item = await Zotero.Items.getAsync(itemID);
if (!item) {
return false;
@@ -72,6 +69,10 @@ class ReaderInstance {
return true;
}
+ get itemID() {
+ return this._itemID;
+ }
+
updateTitle() {
let item = Zotero.Items.get(this._itemID);
let title = item.getField('title');
@@ -464,6 +465,7 @@ class ReaderInstance {
class ReaderTab extends ReaderInstance {
constructor({ itemID, sidebarWidth, sidebarOpen, bottomPlaceholderHeight }) {
super();
+ this._itemID = itemID;
this._sidebarWidth = sidebarWidth;
this._sidebarOpen = sidebarOpen;
this._bottomPlaceholderHeight = bottomPlaceholderHeight;
diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties
index d9104c5b9f..358c28ef02 100644
--- a/chrome/locale/en-US/zotero/zotero.properties
+++ b/chrome/locale/en-US/zotero/zotero.properties
@@ -400,6 +400,8 @@ pane.item.related.count.plural = %S related:
pane.item.parentItem = Parent Item:
pane.context.noParent = No parent item
+pane.context.itemNotes = Item Notes
+pane.context.allNotes = All Notes
noteEditor.editNote = Edit Note
diff --git a/chrome/skin/default/zotero/contextPane.css b/chrome/skin/default/zotero/contextPane.css
index 4a60bd926a..16ad9e2d3e 100644
--- a/chrome/skin/default/zotero/contextPane.css
+++ b/chrome/skin/default/zotero/contextPane.css
@@ -69,3 +69,22 @@
.zotero-context-notes-list {
padding-top: 5px;
}
+
+.zotero-context-pane-editor-parent-line > div {
+ display: flex;
+ align-items: center;
+ padding: 5px 5px;
+}
+
+.zotero-context-pane-editor-parent-line .parent-item-type {
+ margin-right: 3px;
+ width: 16px;
+}
+
+.zotero-context-pane-editor-parent-line .parent-title {
+ flex-grow: 1;
+ width: 0;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
diff --git a/scss/components/_notesList.scss b/scss/components/_notesList.scss
index 13ea798da9..02cbb883a2 100644
--- a/scss/components/_notesList.scss
+++ b/scss/components/_notesList.scss
@@ -16,7 +16,7 @@
&> section > h2 {
font-weight: bold;
- padding: 7px 8px 3px;
+ margin: 7px 8px 3px;
font-size: 13px;
}
}