Implement read/unread functionality in feeds
This commit is contained in:
parent
9686758c7d
commit
2c3eb205ab
|
@ -50,6 +50,7 @@ Zotero.CollectionTreeView = function()
|
|||
'publications',
|
||||
'share',
|
||||
'group',
|
||||
'feedItem',
|
||||
'trash',
|
||||
'bucket'
|
||||
],
|
||||
|
@ -225,10 +226,10 @@ Zotero.CollectionTreeView.prototype.refresh = Zotero.Promise.coroutine(function*
|
|||
}, 0),
|
||||
added++
|
||||
);
|
||||
for (let i = 0, len = groups.length; i < len; i++) {
|
||||
for (let feed of feeds) {
|
||||
this._addRowToArray(
|
||||
newRows,
|
||||
new Zotero.CollectionTreeRow('feed', feeds[i]),
|
||||
new Zotero.CollectionTreeRow('feed', feed),
|
||||
added++
|
||||
);
|
||||
}
|
||||
|
@ -251,10 +252,10 @@ Zotero.CollectionTreeView.prototype.refresh = Zotero.Promise.coroutine(function*
|
|||
}, 0),
|
||||
added++
|
||||
);
|
||||
for (let i = 0, len = groups.length; i < len; i++) {
|
||||
for (let group of groups) {
|
||||
this._addRowToArray(
|
||||
newRows,
|
||||
new Zotero.CollectionTreeRow('group', groups[i]),
|
||||
new Zotero.CollectionTreeRow('group', group),
|
||||
added++
|
||||
);
|
||||
}
|
||||
|
@ -314,6 +315,13 @@ Zotero.CollectionTreeView.prototype.selectWait = Zotero.Promise.method(function
|
|||
* Called by Zotero.Notifier on any changes to collections in the data layer
|
||||
*/
|
||||
Zotero.CollectionTreeView.prototype.notify = Zotero.Promise.coroutine(function* (action, type, ids, extraData) {
|
||||
if (type == 'feed' && action == 'unreadCountUpdated') {
|
||||
for (let i=0; i<ids.length; i++) {
|
||||
this._treebox.invalidateRow(this._rowMap['L' + ids[i]]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!ids || ids.length == 0) && action != 'refresh' && action != 'redraw') {
|
||||
return;
|
||||
}
|
||||
|
@ -2143,6 +2151,8 @@ Zotero.CollectionTreeView.prototype.getCellProperties = function(row, col, prop)
|
|||
}
|
||||
else if (treeRow.isPublications()) {
|
||||
props.push("notwisty");
|
||||
} else if (treeRow.ref && treeRow.ref.unreadCount) {
|
||||
props.push('unread');
|
||||
}
|
||||
|
||||
return props.join(" ");
|
||||
|
|
|
@ -178,6 +178,7 @@ Zotero.Feed.prototype._set = function (prop, val) {
|
|||
Zotero.Feed.prototype._loadDataFromRow = function(row) {
|
||||
Zotero.Feed._super.prototype._loadDataFromRow.call(this, row);
|
||||
|
||||
this._feedName = row._feedName;
|
||||
this._feedUrl = row._feedUrl;
|
||||
this._feedLastCheckError = row._feedLastCheckError || null;
|
||||
this._feedLastCheck = row._feedLastCheck || null;
|
||||
|
@ -274,8 +275,8 @@ Zotero.Feed.prototype._finalizeErase = Zotero.Promise.method(function(env) {
|
|||
|
||||
Zotero.Feed.prototype.getExpiredFeedItemIDs = Zotero.Promise.coroutine(function* () {
|
||||
let sql = "SELECT itemID AS id FROM feedItems "
|
||||
+ "WHERE readTimestamp IS NOT NULL "
|
||||
+ "AND (julianday(readTimestamp, 'utc') + (?) - julianday('now', 'utc')) > 0";
|
||||
+ "WHERE readTime IS NOT NULL "
|
||||
+ "AND (julianday(readTime, 'utc') + (?) - julianday('now', 'utc')) > 0";
|
||||
let expiredIDs = yield Zotero.DB.queryAsync(sql, [{int: this.cleanupAfter}]);
|
||||
return expiredIDs.map(row => row.id);
|
||||
});
|
||||
|
@ -289,7 +290,7 @@ Zotero.Feed.prototype._updateFeed = Zotero.Promise.coroutine(function* () {
|
|||
Zotero.debug("Cleaning up read feed items...");
|
||||
if (expiredItems.length) {
|
||||
Zotero.debug(expiredItems.join(', '));
|
||||
yield Zotero.FeedItems.erase(expiredItems);
|
||||
yield Zotero.FeedItems.eraseTx(expiredItems);
|
||||
} else {
|
||||
Zotero.debug("No expired feed items");
|
||||
}
|
||||
|
@ -301,7 +302,7 @@ Zotero.Feed.prototype._updateFeed = Zotero.Promise.coroutine(function* () {
|
|||
|
||||
try {
|
||||
let fr = new Zotero.FeedReader(this.url);
|
||||
let itemIterator = fr.createItemIterator();
|
||||
let itemIterator = fr.itemIterator;
|
||||
let item, toAdd = [], processedGUIDs = [];
|
||||
while (item = yield itemIterator.next().value) {
|
||||
if (item.dateModified && this.lastUpdate
|
||||
|
@ -320,14 +321,14 @@ Zotero.Feed.prototype._updateFeed = Zotero.Promise.coroutine(function* () {
|
|||
}
|
||||
processedGUIDs.push(item.guid);
|
||||
|
||||
Zotero.debug("New feed item retrieved:");
|
||||
Zotero.debug(item);
|
||||
Zotero.debug("New feed item retrieved:", 5);
|
||||
Zotero.debug(item, 5);
|
||||
|
||||
let feedItem = yield Zotero.FeedItems.getAsyncByGUID(item.guid);
|
||||
if (!feedItem) {
|
||||
feedItem = new Zotero.FeedItem();
|
||||
feedItem.guid = item.guid;
|
||||
feedItem.setCollections([this.id]);
|
||||
feedItem.libraryID = this.id;
|
||||
} else {
|
||||
Zotero.debug("Feed item " + item.guid + " already in library.");
|
||||
if (item.dateModified && feedItem.dateModified
|
||||
|
@ -364,7 +365,7 @@ Zotero.Feed.prototype._updateFeed = Zotero.Promise.coroutine(function* () {
|
|||
|
||||
this.lastCheck = Zotero.Date.dateToSQL(new Date(), true);
|
||||
this.lastCheckError = errorMessage || null;
|
||||
yield this.save({skipEditCheck: true});
|
||||
yield this.saveTx({skipEditCheck: true});
|
||||
});
|
||||
|
||||
Zotero.Feed.prototype.updateFeed = function() {
|
||||
|
@ -380,3 +381,15 @@ Zotero.Feed.prototype.erase = Zotero.Promise.coroutine(function* () {
|
|||
yield Zotero.FeedItems.erase(childItemIDs);
|
||||
return Zotero.Feed._super.prototype.erase.call(this); // Don't tell it to delete child items. They're already gone
|
||||
})
|
||||
|
||||
Zotero.Feed.prototype.updateUnreadCount = Zotero.Promise.coroutine(function* () {
|
||||
let sql = "SELECT " + this._ObjectsClass._primaryDataSQLParts.feedUnreadCount
|
||||
+ this._ObjectsClass.primaryDataSQLFrom
|
||||
+ " AND O.libraryID=?";
|
||||
let newCount = yield Zotero.DB.valueQueryAsync(sql, [this.id]);
|
||||
|
||||
if (newCount != this._feedUnreadCount) {
|
||||
this._feedUnreadCount = newCount;
|
||||
Zotero.Notifier.trigger('unreadCountUpdated', 'feed', this.id);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -132,6 +132,51 @@ Zotero.FeedItem.prototype._saveData = Zotero.Promise.coroutine(function* (env) {
|
|||
yield Zotero.DB.queryAsync(sql, [env.id, this.guid, this._feedItemReadTime]);
|
||||
|
||||
this._clearChanged('feedItemData');
|
||||
|
||||
/* let itemID;
|
||||
if (env.isNew) {
|
||||
// For new items, run this first so we get an item ID
|
||||
yield Zotero.FeedItem._super.prototype._saveData.apply(this, arguments);
|
||||
itemID = env.id;
|
||||
} else {
|
||||
itemID = this.id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!env.isNew) {
|
||||
if (this.hasChanged()) {
|
||||
yield Zotero.FeedItem._super.prototype._saveData.apply(this, arguments);
|
||||
} else {
|
||||
env.skipPrimaryDataReload = true;
|
||||
}
|
||||
Zotero.Notifier.trigger('modify', 'feedItem', itemID);
|
||||
} else {
|
||||
Zotero.Notifier.trigger('add', 'feedItem', itemID);
|
||||
}
|
||||
|
||||
if (env.collectionsAdded || env.collectionsRemoved) {
|
||||
let affectedCollections = (env.collectionsAdded || [])
|
||||
.concat(env.collectionsRemoved || []);
|
||||
if (affectedCollections.length) {
|
||||
let feeds = yield Zotero.Feeds.getAsync(affectedCollections);
|
||||
for (let i=0; i<feeds.length; i++) {
|
||||
feeds[i].updateUnreadCount();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
});
|
||||
|
||||
Zotero.FeedItem.prototype.toggleRead = Zotero.Promise.coroutine(function* (state) {
|
||||
state = state !== undefined ? !!state : !this.isRead;
|
||||
let changed = this.isRead != state;
|
||||
this.isRead = state;
|
||||
if (changed) {
|
||||
yield this.save({skipEditCheck: true, skipDateModifiedUpdate: true});
|
||||
|
||||
yield this.loadCollections();
|
||||
let feed = Zotero.Feeds.get(this.libraryID);
|
||||
feed.updateUnreadCount();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -94,6 +94,19 @@ Zotero.FeedItems = new Proxy(function() {
|
|||
return this.getAsync(id);
|
||||
});
|
||||
|
||||
this.toggleReadById = Zotero.Promise.coroutine(function* (ids, state) {
|
||||
if (!Array.isArray(ids)) {
|
||||
if (typeof ids != 'string') throw new Error('ids must be a string or array in Zotero.FeedItems.toggleReadById');
|
||||
|
||||
ids = [ids];
|
||||
}
|
||||
|
||||
let items = yield this.getAsync(ids);
|
||||
for (let i=0; i<items.length; i++) {
|
||||
items[i].toggleRead(state);
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
}.call({}),
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
***** END LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
// Add some feed methods, but otherwise proxy to Zotero.Collections
|
||||
// Mimics Zotero.Libraries
|
||||
Zotero.Feeds = new function() {
|
||||
this._cache = null;
|
||||
|
||||
|
@ -105,12 +105,15 @@ Zotero.Feeds = new function() {
|
|||
.map(id => Zotero.Libraries.get(id));
|
||||
}
|
||||
|
||||
this.get = Zotero.Libraries.get;
|
||||
|
||||
this.haveFeeds = function() {
|
||||
if (!this._cache) throw new Error("Zotero.Feeds cache is not initialized");
|
||||
|
||||
return !!Object.keys(this._cache.urlByLibraryID).length
|
||||
}
|
||||
|
||||
let globalFeedCheckDelay = Zotero.Promise.resolve();
|
||||
this.scheduleNextFeedCheck = Zotero.Promise.coroutine(function* () {
|
||||
Zotero.debug("Scheduling next feed update.");
|
||||
let sql = "SELECT ( CASE "
|
||||
|
@ -146,4 +149,24 @@ Zotero.Feeds = new function() {
|
|||
Zotero.debug("No feeds with auto-update.");
|
||||
}
|
||||
});
|
||||
|
||||
this.updateFeeds = Zotero.Promise.coroutine(function* () {
|
||||
let sql = "SELECT libraryID AS id FROM feeds "
|
||||
+ "WHERE refreshInterval IS NOT NULL "
|
||||
+ "AND ( lastCheck IS NULL "
|
||||
+ "OR (julianday(lastCheck, 'utc') + (refreshInterval/1440) - julianday('now', 'utc')) <= 0 )";
|
||||
let needUpdate = yield Zotero.DB.queryAsync(sql).map(row => row.id);
|
||||
Zotero.debug("Running update for feeds: " + needUpdate.join(', '));
|
||||
let feeds = Zotero.Libraries.get(needUpdate);
|
||||
let updatePromises = [];
|
||||
for (let i=0; i<feeds.length; i++) {
|
||||
updatePromises.push(feeds[i]._updateFeed());
|
||||
}
|
||||
|
||||
return Zotero.Promise.settle(updatePromises)
|
||||
.then(() => {
|
||||
Zotero.debug("All feed updates done.");
|
||||
this.scheduleNextFeedCheck()
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1660,6 +1660,9 @@ Zotero.Item.prototype._saveData = Zotero.Promise.coroutine(function* (env) {
|
|||
|
||||
let toAdd = Zotero.Utilities.arrayDiff(newCollections, oldCollections);
|
||||
let toRemove = Zotero.Utilities.arrayDiff(oldCollections, newCollections);
|
||||
|
||||
env.collectionsAdded = toAdd;
|
||||
env.collectionsRemoved = toRemove;
|
||||
|
||||
if (toAdd.length) {
|
||||
for (let i=0; i<toAdd.length; i++) {
|
||||
|
|
|
@ -53,9 +53,9 @@ Zotero.ItemTreeView = function (collectionTreeRow, sourcesOnly) {
|
|||
|
||||
this._refreshPromise = Zotero.Promise.resolve();
|
||||
|
||||
this._unregisterID = Zotero.Notifier.registerObserver(
|
||||
this._unregisterID = Zotero.Notifier.registerObserver(
|
||||
this,
|
||||
['item', 'collection-item', 'item-tag', 'share-items', 'bucket'],
|
||||
['item', 'collection-item', 'item-tag', 'share-items', 'bucket', 'feedItem'],
|
||||
'itemTreeView',
|
||||
50
|
||||
);
|
||||
|
@ -391,6 +391,14 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
|||
return;
|
||||
}
|
||||
|
||||
// FeedItem may have changed read/unread state
|
||||
if (type == 'feedItem' && action == 'modify') {
|
||||
for (let i=0; i<ids.length; i++) {
|
||||
this._treebox.invalidateRow(this._itemRowMap[ids[i]]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear item type icon and tag colors when a tag is added to or removed from an item
|
||||
if (type == 'item-tag') {
|
||||
// TODO: Only update if colored tag changed?
|
||||
|
@ -526,12 +534,9 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
|||
// Since a remove involves shifting of rows, we have to do it in order,
|
||||
// so sort the ids by row
|
||||
var rows = [];
|
||||
let push = action == 'delete' || action == 'trash';
|
||||
for (var i=0, len=ids.length; i<len; i++) {
|
||||
let push = false;
|
||||
if (action == 'delete' || action == 'trash') {
|
||||
push = true;
|
||||
}
|
||||
else {
|
||||
if (!push) {
|
||||
push = !collectionTreeRow.ref.hasItem(ids[i]);
|
||||
}
|
||||
// Row might already be gone (e.g. if this is a child and
|
||||
|
@ -567,7 +572,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (action == 'modify')
|
||||
else if (type == 'item' && action == 'modify')
|
||||
{
|
||||
// Clear row caches
|
||||
var items = yield Zotero.Items.getAsync(ids);
|
||||
|
@ -685,7 +690,7 @@ Zotero.ItemTreeView.prototype.notify = Zotero.Promise.coroutine(function* (actio
|
|||
}
|
||||
}
|
||||
}
|
||||
else if(action == 'add')
|
||||
else if(type == 'item' && action == 'add')
|
||||
{
|
||||
let items = yield Zotero.Items.getAsync(ids);
|
||||
|
||||
|
@ -3054,56 +3059,25 @@ Zotero.ItemTreeView.prototype.getCellProperties = function(row, col, prop) {
|
|||
|
||||
// Mark items not matching search as context rows, displayed in gray
|
||||
if (this._searchMode && !this._searchItemIDs[itemID]) {
|
||||
// <=Fx21
|
||||
if (prop) {
|
||||
var aServ = Components.classes["@mozilla.org/atom-service;1"].
|
||||
getService(Components.interfaces.nsIAtomService);
|
||||
prop.AppendElement(aServ.getAtom("contextRow"));
|
||||
}
|
||||
// Fx22+
|
||||
else {
|
||||
props.push("contextRow");
|
||||
}
|
||||
props.push("contextRow");
|
||||
}
|
||||
|
||||
// Mark hasAttachment column, which needs special image handling
|
||||
if (col.id == 'zotero-items-column-hasAttachment') {
|
||||
// <=Fx21
|
||||
if (prop) {
|
||||
var aServ = Components.classes["@mozilla.org/atom-service;1"].
|
||||
getService(Components.interfaces.nsIAtomService);
|
||||
prop.AppendElement(aServ.getAtom("hasAttachment"));
|
||||
}
|
||||
// Fx22+
|
||||
else {
|
||||
props.push("hasAttachment");
|
||||
}
|
||||
props.push("hasAttachment");
|
||||
|
||||
// Don't show pie for open parent items, since we show it for the
|
||||
// child item
|
||||
if (this.isContainer(row) && this.isContainerOpen(row)) {
|
||||
return props.join(" ");
|
||||
}
|
||||
|
||||
var num = Zotero.Sync.Storage.getItemDownloadImageNumber(treeRow.ref);
|
||||
//var num = Math.round(new Date().getTime() % 10000 / 10000 * 64);
|
||||
if (num !== false) {
|
||||
// <=Fx21
|
||||
if (prop) {
|
||||
if (!aServ) {
|
||||
var aServ = Components.classes["@mozilla.org/atom-service;1"].
|
||||
getService(Components.interfaces.nsIAtomService);
|
||||
}
|
||||
prop.AppendElement(aServ.getAtom("pie"));
|
||||
prop.AppendElement(aServ.getAtom("pie" + num));
|
||||
}
|
||||
// Fx22+
|
||||
else {
|
||||
props.push("pie", "pie" + num);
|
||||
}
|
||||
if (!this.isContainer(row) || !this.isContainerOpen(row)) {
|
||||
var num = Zotero.Sync.Storage.getItemDownloadImageNumber(treeRow.ref);
|
||||
//var num = Math.round(new Date().getTime() % 10000 / 10000 * 64);
|
||||
if (num !== false) props.push("pie", "pie" + num);
|
||||
}
|
||||
}
|
||||
|
||||
// Style unread items in feeds
|
||||
if (treeRow.ref.isFeedItem && !treeRow.ref.isRead) props.push('unread');
|
||||
|
||||
return props.join(" ");
|
||||
}
|
||||
|
||||
|
|
|
@ -95,8 +95,9 @@ Zotero.Notifier = new function(){
|
|||
* Possible values:
|
||||
*
|
||||
* event: 'add', 'modify', 'delete', 'move' ('c', for changing parent),
|
||||
* 'remove' (ci, it), 'refresh', 'redraw', 'trash'
|
||||
* type - 'collection', 'search', 'item', 'collection-item', 'item-tag', 'tag', 'group', 'relation'
|
||||
* 'remove' (ci, it), 'refresh', 'redraw', 'trash', 'unreadCountUpdated'
|
||||
* type - 'collection', 'search', 'item', 'collection-item', 'item-tag', 'tag',
|
||||
* 'group', 'relation', 'feed', 'feedItem'
|
||||
* ids - single id or array of ids
|
||||
*
|
||||
* Notes:
|
||||
|
|
|
@ -501,9 +501,9 @@ var ZoteroPane = new function()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
function handleKeyUp(event, from) {
|
||||
if (from == 'zotero-pane') {
|
||||
function handleKeyUp(event) {
|
||||
var from = event.originalTarget.id;
|
||||
if (from == 'zotero-items-tree') {
|
||||
if ((Zotero.isWin && event.keyCode == 17) ||
|
||||
(!Zotero.isWin && event.keyCode == 18)) {
|
||||
if (this.highlightTimer) {
|
||||
|
@ -511,6 +511,33 @@ var ZoteroPane = new function()
|
|||
this.highlightTimer = null;
|
||||
}
|
||||
ZoteroPane_Local.collectionsView.setHighlightedRows();
|
||||
return;
|
||||
} else if (event.keyCode == event.DOM_VK_BACK_QUOTE) {
|
||||
// Toggle read/unread
|
||||
let row = this.collectionsView.getRow(this.collectionsView.selection.currentIndex);
|
||||
if (!row || !row.isFeed()) return;
|
||||
if(itemReadTimeout) {
|
||||
itemReadTimeout.cancel();
|
||||
itemReadTimeout = null;
|
||||
}
|
||||
|
||||
let itemIDs = this.getSelectedItems(true);
|
||||
Zotero.FeedItems.getAsync(itemIDs)
|
||||
.then(function(feedItems) {
|
||||
// Determine what most items are set to;
|
||||
let allUnread = true;
|
||||
for (let item of feedItems) {
|
||||
if (item.isRead) {
|
||||
allUnread = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If something is unread, toggle all read by default
|
||||
for (let i=0; i<feedItems.length; i++) {
|
||||
feedItems[i].toggleRead(!allUnread);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -594,21 +621,6 @@ var ZoteroPane = new function()
|
|||
//event.preventDefault();
|
||||
//event.stopPropagation();
|
||||
return;
|
||||
} else if (event.keyCode == event.DOM_VK_BACK_QUOTE) {
|
||||
// Toggle read/unread
|
||||
if (!this.collectionsView.selection.currentIndex) return;
|
||||
let row = this.collectionsView.getRow(this.collectionsView.selection.currentIndex);
|
||||
if (!row || !row.isFeed()) return;
|
||||
|
||||
if(itemReadTimeout) {
|
||||
itemReadTimeout.cancel();
|
||||
itemReadTimeout = null;
|
||||
}
|
||||
|
||||
let itemIDs = this.getSelectedItems(true);
|
||||
for (var i=0; i<itemIDs; i++) {
|
||||
this.markItemRead(itemIDs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1377,15 +1389,11 @@ var ZoteroPane = new function()
|
|||
tabs.selectedIndex = document.getElementById('zotero-view-item').selectedIndex;
|
||||
}
|
||||
|
||||
if (collectionTreeRow.isFeed()) {
|
||||
// Fire timer for read item
|
||||
let feedItem = yield Zotero.FeedItems.getAsync(item.id);
|
||||
if (feedItem) {
|
||||
this.startItemReadTimeout(feedItem.id);
|
||||
if (item.isFeedItem) {
|
||||
this.startItemReadTimeout(item.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Zero or multiple items selected
|
||||
else {
|
||||
var count = this.itemsView.selection.count;
|
||||
|
@ -4290,14 +4298,6 @@ var ZoteroPane = new function()
|
|||
});
|
||||
|
||||
|
||||
this.markItemRead = Zotero.Promise.coroutine(function* (feedItemID, toggle) {
|
||||
let feedItem = yield Zotero.FeedItems.getAsync(feedItemID);
|
||||
if (!feedItem) return;
|
||||
|
||||
feedItem.isRead = toggle !== undefined ? !!toggle : !feedItem.isRead;
|
||||
yield feedItem.save({skipEditCheck: true, skipDateModifiedUpdate: true});
|
||||
})
|
||||
|
||||
let itemReadTimeout;
|
||||
this.startItemReadTimeout = function(feedItemID) {
|
||||
if (itemReadTimeout) {
|
||||
|
@ -4305,8 +4305,18 @@ var ZoteroPane = new function()
|
|||
itemReadTimeout = null;
|
||||
}
|
||||
|
||||
itemReadTimeout = Zotero.Promise.delay(3000)
|
||||
let feedItem;
|
||||
itemReadTimeout = Zotero.FeedItems.getAsync(feedItemID)
|
||||
.cancellable()
|
||||
.then(function(newFeedItem) {
|
||||
if (!newFeedItem) {
|
||||
throw new Zotero.Promise.CancellationError('Not a FeedItem');
|
||||
} else if(newFeedItem.isRead) {
|
||||
throw new Zotero.Promise.CancellationError('FeedItem already read.');
|
||||
}
|
||||
feedItem = newFeedItem;
|
||||
})
|
||||
.delay(3000)
|
||||
.then(() => {
|
||||
itemReadTimeout = null;
|
||||
// Check to make sure we're still on the same item
|
||||
|
@ -4315,7 +4325,15 @@ var ZoteroPane = new function()
|
|||
let row = this.itemsView.getRow(this.itemsView.selection.currentIndex);
|
||||
if (!row || !row.ref || !row.ref.id == feedItemID) return;
|
||||
|
||||
return this.markItemRead(feedItemID, true);
|
||||
return feedItem.toggleRead(true);
|
||||
})
|
||||
.catch(function(e) {
|
||||
if (e instanceof Zotero.Promise.CancellationError) {
|
||||
Zotero.debug(e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
Zotero.debug(e, 1);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -215,6 +215,12 @@
|
|||
color: inherit;
|
||||
}
|
||||
|
||||
/* Style unread items/collections in bold */
|
||||
#zotero-items-tree treechildren::-moz-tree-cell-text(unread),
|
||||
#zotero-collections-tree treechildren::-moz-tree-cell-text(unread) {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#zotero-items-pane
|
||||
{
|
||||
min-width: 290px;
|
||||
|
|
Loading…
Reference in New Issue
Block a user