summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/about/version.gmi2
-rw-r--r--src/feeds.c10
2 files changed, 12 insertions, 0 deletions
diff --git a/res/about/version.gmi b/res/about/version.gmi
index a5e0d01f..6b2e9a45 100644
--- a/res/about/version.gmi
+++ b/res/about/version.gmi
@@ -13,9 +13,11 @@ New features:
13* Windows: Automatic updates using the WinSparkle library. 13* Windows: Automatic updates using the WinSparkle library.
14 14
15Changes and enhancements: 15Changes and enhancements:
16* Navigating back and forward in history will skip input query prompts (status 1x), showing only the query results.
16* The resource bundle (resources.lgr) is now a regular ZIP archive. This allows it to do double duty as a fontpack containing the built-in fonts. The archive contains a version number to avoid use of obsolete resources. 17* The resource bundle (resources.lgr) is now a regular ZIP archive. This allows it to do double duty as a fontpack containing the built-in fonts. The archive contains a version number to avoid use of obsolete resources.
17 18
18Fixes: 19Fixes:
20* Handling duplicate feed entries: if multiple entries in a feed have the same URL, only handle the first one.
19 21
20## 1.8.3 22## 1.8.3
21* Fixed clicking on UI elements that are over the page top banner. The banner would always get clicked instead. 23* Fixed clicking on UI elements that are over the page top banner. The banner would always get clicked instead.
diff --git a/src/feeds.c b/src/feeds.c
index baec6870..26b3d6db 100644
--- a/src/feeds.c
+++ b/src/feeds.c
@@ -386,10 +386,18 @@ static iBool updateEntries_Feeds_(iFeeds *d, iBool isHeadings, uint32_t sourceId
386 setUrlKept_Visited(visited_App(), &entry->url, iTrue); 386 setUrlKept_Visited(visited_App(), &entry->url, iTrue);
387 } 387 }
388 } 388 }
389 iStringSet *handledUrls = new_StringSet();
389 lock_Mutex(d->mtx); 390 lock_Mutex(d->mtx);
390 iForEach(PtrArray, i, incoming) { 391 iForEach(PtrArray, i, incoming) {
391 iFeedEntry *entry = i.ptr; 392 iFeedEntry *entry = i.ptr;
392 size_t pos; 393 size_t pos;
394 if (contains_StringSet(handledUrls, &entry->url)) {
395 /* This is a duplicate. Each unique URL is handled only once. */
396 delete_FeedEntry(entry);
397 remove_PtrArrayIterator(&i);
398 continue;
399 }
400 insert_StringSet(handledUrls, &entry->url);
393 if (locate_SortedArray(&d->entries, &entry, &pos)) { 401 if (locate_SortedArray(&d->entries, &entry, &pos)) {
394 iFeedEntry *existing = *(iFeedEntry **) at_SortedArray(&d->entries, pos); 402 iFeedEntry *existing = *(iFeedEntry **) at_SortedArray(&d->entries, pos);
395 iAssert(!isHeadingEntry_FeedEntry_(existing)); 403 iAssert(!isHeadingEntry_FeedEntry_(existing));
@@ -422,6 +430,8 @@ static iBool updateEntries_Feeds_(iFeeds *d, iBool isHeadings, uint32_t sourceId
422 remove_PtrArrayIterator(&i); 430 remove_PtrArrayIterator(&i);
423 } 431 }
424 unlock_Mutex(d->mtx); 432 unlock_Mutex(d->mtx);
433 fflush(stdout);
434 iRelease(handledUrls);
425 } 435 }
426 return gotNew; 436 return gotNew;
427} 437}