LCOV - code coverage report
Current view: top level - src/models - LisvelFeedItem.cpp (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 89.6 % 67 60
Test Date: 2026-03-23 10:19:47 Functions: 100.0 % 3 3

            Line data    Source code
       1              : #include "LisvelFeedItem.h"
       2              : #include "src/models/NewsItem.h"
       3              : #include "src/models/NewsList.h"
       4              : #include "../utilities/FangLogging.h"
       5              : 
       6           84 : LisvelFeedItem::LisvelFeedItem(const qint64 id, const qint32 ordinal, const QString& title, QObject *parent) :
       7           84 :     FeedItem(id, ordinal, title, "", QDateTime(), 0, QUrl(), QUrl(), "", QUrl(), QDateTime(), -1, true, FeedTypeRSS, parent)
       8              : {
       9           84 : }
      10              : 
      11           83 : void LisvelFeedItem::setBookmark(qint64 toBookmarkID)
      12              : {
      13              :     // Call base class implementation.
      14           83 :     FeedItem::setBookmark(toBookmarkID);
      15              : 
      16              :     // Get the position data (timestamp, id) for Lisvel ordering comparison.
      17           83 :     if (toBookmarkID >= 0) {
      18           82 :         NewsItem* item = getNewsList()->fullNewsItemForID(toBookmarkID);
      19           82 :         if (item) {
      20           79 :             _bookmarkPosition = NewsPosition(toBookmarkID, item->getTimestamp());
      21          158 :             qCDebug(logModel) << "LisvelFeedItem::setBookmark: ID" << toBookmarkID
      22           79 :                               << "timestamp" << item->getTimestamp().toString(Qt::ISODate);
      23              :         } else {
      24              :             // Item not in memory: clear the position so canBookmark will try to initialize
      25              :             // with the ID only (in other words, not the timestamp.)
      26            3 :             _bookmarkPosition = NewsPosition();
      27            6 :             qCDebug(logModel) << "LisvelFeedItem::setBookmark: ID" << toBookmarkID
      28            3 :                               << "not in memory, cleared position for lazy init";
      29              :         }
      30              :     } else {
      31            1 :         _bookmarkPosition = NewsPosition();
      32            2 :         qCDebug(logModel) << "LisvelFeedItem::setBookmark: Clearing bookmark";
      33              :     }
      34           83 : }
      35              : 
      36          205 : bool LisvelFeedItem::canBookmark(qint64 proposedBookmarkID, bool allowBackward)
      37              : {
      38              :     // Invalid ID.
      39          205 :     if (proposedBookmarkID < -1) {
      40            4 :         qCDebug(logModel) << "canBookmark: REJECTED - invalid ID" << proposedBookmarkID;
      41            2 :         return false;
      42              :     }
      43              : 
      44              :     // Given no current bookmark, anything will do.
      45          203 :     if (getBookmarkID() < 0) {
      46           12 :         qCDebug(logModel) << "canBookmark: ALLOWED - no current bookmark, accepting" << proposedBookmarkID;
      47            6 :         return true;
      48              :     }
      49              : 
      50              :     // No change.
      51          197 :     if (getBookmarkID() == proposedBookmarkID) {
      52              :         // Don't log this - it's very common and noisy
      53            5 :         return false;
      54              :     }
      55              : 
      56              :     // We can bookmark anything in this situation.
      57          192 :     if (allowBackward) {
      58           32 :         qCDebug(logModel) << "canBookmark: ALLOWED - allowBackward=true, proposed=" << proposedBookmarkID;
      59           16 :         return true;
      60              :     }
      61              : 
      62              :     // Get indices of both items in the list. We need to respect the order of this list as it
      63              :     // is expected to match what's displayed to the user on the web view.
      64          176 :     qsizetype proposedIndex = getNewsList()->fullIndexForItemID(proposedBookmarkID);
      65          176 :     qsizetype currentIndex = getNewsList()->fullIndexForItemID(getBookmarkID());
      66              : 
      67          352 :     qCDebug(logModel) << "canBookmark: proposed=" << proposedBookmarkID << "idx=" << proposedIndex
      68          176 :                       << "current=" << getBookmarkID() << "idx=" << currentIndex
      69          176 :                       << "listSize=" << getNewsList()->size();
      70              : 
      71              :     // Proposed item not in list.
      72          176 :     if (proposedIndex < 0) {
      73            6 :         qCDebug(logModel) << "canBookmark: REJECTED - proposed ID" << proposedBookmarkID << "not in list";
      74            3 :         return false;
      75              :     }
      76              : 
      77              :     // Both items in list, so compare the indicies.
      78          173 :     if (currentIndex >= 0) {
      79          169 :         bool result = proposedIndex > currentIndex;
      80          169 :         if (!result) {
      81          188 :             qCDebug(logModel) << "canBookmark: REJECTED - index" << proposedIndex << "<=" << currentIndex;
      82              :         }
      83          169 :         return result;
      84              :     }
      85              : 
      86              :     // Current bookmark not in list (was trimmed) so use NewsPosition comparison.
      87            8 :     qCDebug(logModel) << "canBookmark: Current bookmark" << getBookmarkID() << "not in list, using NewsPosition"
      88            4 :                       << "valid=" << _bookmarkPosition.isValid();
      89              : 
      90              :     // First, try to lazily initialize the bookmark position if we have the item now.
      91              :     // Also reinitialize if the position ID doesn't match the current bookmark ID
      92              :     // (could happen if state got out of sync).
      93            4 :     if (!_bookmarkPosition.isValid() || _bookmarkPosition.id() != getBookmarkID()) {
      94            1 :         NewsItem* bookmarkItem = getNewsList()->fullNewsItemForID(getBookmarkID());
      95            1 :         if (bookmarkItem) {
      96            0 :             _bookmarkPosition = NewsPosition(getBookmarkID(), bookmarkItem->getTimestamp());
      97            0 :             qCDebug(logModel) << "canBookmark: Lazy-initialized position to"
      98            0 :                               << _bookmarkPosition.timestamp().toString(Qt::ISODate);
      99              :         } else {
     100              :             // Can't find the item - clear stale position if IDs don't match
     101            1 :             if (_bookmarkPosition.isValid() && _bookmarkPosition.id() != getBookmarkID()) {
     102            0 :                 qCDebug(logModel) << "canBookmark: Clearing stale position (ID mismatch:"
     103            0 :                                   << _bookmarkPosition.id() << "vs" << getBookmarkID() << ")";
     104            0 :                 _bookmarkPosition = NewsPosition();
     105              :             }
     106              :         }
     107              :     }
     108              : 
     109              :     // Use NewsPosition comparison if available.
     110            4 :     if (_bookmarkPosition.isValid()) {
     111              :         // positionAt() works even if the item is unloaded.
     112            3 :         NewsPosition proposedPosition = getNewsList()->positionAt(proposedIndex);
     113              : 
     114            3 :         bool isAfter = proposedPosition.isAfter(_bookmarkPosition);
     115            6 :         qCDebug(logModel) << "canBookmark: NewsPosition comparison:"
     116            6 :                           << "proposed(" << proposedPosition.id() << "," << proposedPosition.timestamp().toString(Qt::ISODate) << ")"
     117            3 :                           << (isAfter ? ">" : "<=")
     118            3 :                           << "bookmark(" << _bookmarkPosition.id() << "," << _bookmarkPosition.timestamp().toString(Qt::ISODate) << ")";
     119              : 
     120            3 :         if (isAfter) {
     121            0 :             return true;
     122              :         }
     123            3 :         return false;
     124            3 :     }
     125              : 
     126              :     // No valid position available: this shouldn't happen.
     127            2 :     qCDebug(logModel) << "canBookmark: REJECTED - no valid bookmark position available";
     128            1 :     return false;
     129              : }
        

Generated by: LCOV version 2.0-1