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 : }
|