Add Clear All Last Read… to Recently Read context menu

This commit is contained in:
Abe Jellinek 2026-04-07 15:03:27 -04:00
parent 4b14ca9af4
commit 1ac5ad2c84
4 changed files with 65 additions and 2 deletions

View file

@ -189,6 +189,37 @@ Zotero.Items = function () {
};
/**
* Clear lastRead from all attachments in a library.
*
* @param {Integer} libraryID
*/
this.clearAllLastRead = async function (libraryID) {
let sql = "SELECT itemID FROM itemAttachments WHERE lastRead IS NOT NULL "
+ "AND itemID IN (SELECT itemID FROM items WHERE libraryID = ?)";
let ids = await Zotero.DB.columnQueryAsync(sql, [libraryID]);
if (!ids.length) {
return;
}
let items = await this.getAsync(ids);
await Zotero.Utilities.Internal.forEachChunkAsync(
items,
100,
async (chunk) => {
await Zotero.DB.executeTransaction(async () => {
for (let item of chunk) {
item.attachmentLastRead = null;
await item.save({ skipDateModifiedUpdate: true, skipEditCheck: true });
}
});
}
);
this._lastReadCutoffs.delete(libraryID);
};
//
// Bulk data loading functions
//

View file

@ -2480,6 +2480,25 @@ var ZoteroPane = new function () {
}
}
this.clearAllLastRead = async function () {
let collectionTreeRow = this.getCollectionTreeRow();
if (!collectionTreeRow.isRecentlyRead()) {
return;
}
let result = Services.prompt.confirm(
window,
Zotero.getString('general.warning'),
Zotero.getString('recently-read-clear-all-confirm')
);
if (!result) {
return;
}
await Zotero.Items.clearAllLastRead(collectionTreeRow.ref.libraryID);
};
/**
* Check whether every selected item can be restored from trash
*
@ -3396,6 +3415,10 @@ var ZoteroPane = new function () {
id: "deleteCollection",
oncommand: () => this.deleteSelectedCollection()
},
{
id: "clearAllLastRead",
oncommand: () => this.clearAllLastRead()
},
{
id: "deleteCollectionAndItems",
oncommand: () => this.deleteSelectedCollection(true)
@ -3588,13 +3611,18 @@ var ZoteroPane = new function () {
else if (collectionTreeRow.isTrash()) {
show = ['emptyTrash'];
}
else if (collectionTreeRow.isDuplicates() || collectionTreeRow.isUnfiled() || collectionTreeRow.isRecentlyRead()
|| collectionTreeRow.isRetracted()) {
else if (collectionTreeRow.isDuplicates() || collectionTreeRow.isUnfiled() || collectionTreeRow.isRetracted()) {
show = ['deleteCollection'];
m.deleteCollection.setAttribute('label', Zotero.getString('general.hide'));
useHideOrDelete = "hide";
}
else if (collectionTreeRow.isRecentlyRead()) {
show = ['deleteCollection', 'clearAllLastRead'];
m.deleteCollection.setAttribute('label', Zotero.getString('general.hide'));
useHideOrDelete = "hide";
}
else if (collectionTreeRow.isHeader()) {
}
else if (collectionTreeRow.isPublications()) {

View file

@ -966,6 +966,7 @@
</menupopup>
</menu>
<menuitem class="zotero-menuitem-delete-collection"/>
<menuitem class="zotero-menuitem-clear-all-last-read" data-l10n-id="collections-menu-clear-all-last-read"/>
<menuitem class="zotero-menuitem-move-to-trash"/>
<menuseparator/>
<menuitem class="zotero-menuitem-export"/>

View file

@ -185,6 +185,9 @@ collections-menu-show-recently-read =
.label = Show { recently-read }
item-menu-remove-from-recently-read =
.label = Remove from { recently-read }…
collections-menu-clear-all-last-read =
.label = Clear All Last Read…
recently-read-clear-all-confirm = All Last Read dates in this library will be erased.
collections-menu-rename-collection =
.label = Rename Collection
collections-menu-edit-saved-search =