diff --git a/src/gui/src/favorite-window.cpp b/src/gui/src/favorite-window.cpp index d37445d76..1ca9e3ac8 100644 --- a/src/gui/src/favorite-window.cpp +++ b/src/gui/src/favorite-window.cpp @@ -115,10 +115,14 @@ void FavoriteWindow::save() monitors[0] = rep; } + // Only keep the last images if the "last viewed" datetime is unchanged + const QMap lastImages = oldFav.getLastViewed() == ui->lastViewedDateTimeEdit->dateTime() ? oldFav.getLastImages() : QMap(); + m_favorite = Favorite( ui->tagLineEdit->text(), ui->noteSpinBox->value(), ui->lastViewedDateTimeEdit->dateTime(), + lastImages, monitors, savePath("thumbs/" + m_favorite.getName(true) + ".png"), ui->postFilteringLineEdit->text().split(' ', Qt::SkipEmptyParts), diff --git a/src/gui/src/tabs/favorites-tab.cpp b/src/gui/src/tabs/favorites-tab.cpp index c18e3676e..15ee52f3e 100644 --- a/src/gui/src/tabs/favorites-tab.cpp +++ b/src/gui/src/tabs/favorites-tab.cpp @@ -212,14 +212,23 @@ void FavoritesTab::updateFavorites() void FavoritesTab::load() { updateTitle(); + m_newLastImages.clear(); loadTags(m_currentTags.trimmed().split(' ', Qt::SkipEmptyParts)); } bool FavoritesTab::validateImage(const QSharedPointer &img, QString &error) { - bool dateOk = img->createdAt() > m_loadFavorite || img->createdAt().isNull(); - return dateOk && SearchTab::validateImage(img, error); + bool dateOk = img->createdAt().isNull() || img->createdAt() > m_loadFavorite; + + const QVariantMap lastIdentity = m_lastImages.value(img->parentSite()->url()); + bool idOk = !lastIdentity.contains("id") || img->id() > lastIdentity["id"].toULongLong(); + + if (dateOk && idOk && !m_newLastImages.contains(img->parentSite()->url())) { + m_newLastImages[img->parentSite()->url()] = img->identity(true); + } + + return dateOk && idOk && SearchTab::validateImage(img, error); } void FavoritesTab::write(QJsonObject &json) const @@ -305,6 +314,7 @@ void FavoritesTab::loadFavorite(const QString &name) Favorite fav = m_favorites[index]; m_currentTags = fav.getName(); m_loadFavorite = fav.getLastViewed(); + m_lastImages = fav.getLastImages(); m_postFiltering->setPlainText(fav.getPostFiltering().join(' ')); if (!fav.getSites().isEmpty()) { @@ -348,7 +358,7 @@ void FavoritesTab::viewed() m_profile->emitFavorite(); } -void FavoritesTab::setFavoriteViewed(const QString &tag, const QDateTime &date) +void FavoritesTab::setFavoriteViewed(const QString &tag, const QSharedPointer &img) { log(QStringLiteral("Marking \"%1\" as viewed...").arg(tag)); @@ -359,14 +369,21 @@ void FavoritesTab::setFavoriteViewed(const QString &tag, const QDateTime &date) Favorite &fav = m_favorites[index]; - if (!date.isValid()) { + if (img.isNull()) { fav.setLastViewed(QDateTime::currentDateTime()); for (Monitor &monitor : fav.getMonitors()) { monitor.setCumulated(0, true); } + + for (auto it = m_newLastImages.constBegin(); it != m_newLastImages.constEnd(); ++it) { + fav.setLastImage(it.key(), it.value()); + } } else { - fav.setLastViewed(date); + if (img->createdAt().isValid()) { + fav.setLastViewed(img->createdAt()); + } + fav.setLastImage(img->parentSite()->url(), img->identity(true)); } DONE(); @@ -414,7 +431,7 @@ void FavoritesTab::thumbnailContextMenu(QMenu *menu, const QSharedPointer { SearchTab::thumbnailContextMenu(menu, img); - if (m_currentTags.isEmpty() || !img->createdAt().isValid()) { + if (m_currentTags.isEmpty()) { return; } @@ -423,7 +440,7 @@ void FavoritesTab::thumbnailContextMenu(QMenu *menu, const QSharedPointer // Mark as "last viewed" auto *actionMarkAsLastViewed = new QAction(QIcon(":/images/icons/eye.png"), tr("Mark as last viewed"), menu); connect(actionMarkAsLastViewed, &QAction::triggered, [this, img]() { - this->setFavoriteViewed(m_currentTags, img->createdAt()); + this->setFavoriteViewed(m_currentTags, img); }); menu->insertAction(first, actionMarkAsLastViewed); diff --git a/src/gui/src/tabs/favorites-tab.h b/src/gui/src/tabs/favorites-tab.h index c4b3e9ef7..169675d2c 100644 --- a/src/gui/src/tabs/favorites-tab.h +++ b/src/gui/src/tabs/favorites-tab.h @@ -47,7 +47,7 @@ class FavoritesTab : public SearchTab void checkFavorites(); void loadNextFavorite(); void favoritesBack(); - void setFavoriteViewed(const QString &tag, const QDateTime &date = {}); + void setFavoriteViewed(const QString &tag, const QSharedPointer &img = {}); void viewed(); // Others void closeEvent(QCloseEvent *event) override; @@ -61,6 +61,7 @@ class FavoritesTab : public SearchTab QDateTime m_loadFavorite; QString m_currentTags; int m_currentFav; + QMap m_lastImages, m_newLastImages; FixedSizeGridLayout *m_favoritesLayout; }; diff --git a/src/lib/src/models/favorite.cpp b/src/lib/src/models/favorite.cpp index 3daad0760..464a364a3 100644 --- a/src/lib/src/models/favorite.cpp +++ b/src/lib/src/models/favorite.cpp @@ -13,19 +13,21 @@ Favorite::Favorite(QString name) - : Favorite(std::move(name), 50, QDateTime::currentDateTime(), QString()) + : Favorite(std::move(name), 50, QDateTime::currentDateTime(), {}, QString()) {} -Favorite::Favorite(QString name, int note, QDateTime lastViewed, QString imagePath, QStringList postFiltering, QList sites) - : Favorite(std::move(name), note, std::move(lastViewed), QList(), std::move(imagePath), std::move(postFiltering), std::move(sites)) +Favorite::Favorite(QString name, int note, QDateTime lastViewed, QMap lastImages, QString imagePath, QStringList postFiltering, QList sites) + : Favorite(std::move(name), note, std::move(lastViewed), std::move(lastImages), QList(), std::move(imagePath), std::move(postFiltering), std::move(sites)) {} -Favorite::Favorite(QString name, int note, QDateTime lastViewed, QList monitors, QString imagePath, QStringList postFiltering, QList sites) - : m_name(std::move(name)), m_note(note), m_lastViewed(std::move(lastViewed)), m_monitors(std::move(monitors)), m_imagePath(std::move(imagePath)), m_postFiltering(std::move(postFiltering)), m_sites(std::move(sites)) +Favorite::Favorite(QString name, int note, QDateTime lastViewed, QMap lastImages, QList monitors, QString imagePath, QStringList postFiltering, QList sites) + : m_name(std::move(name)), m_note(note), m_lastViewed(std::move(lastViewed)), m_lastImages(std::move(lastImages)), m_monitors(std::move(monitors)), m_imagePath(std::move(imagePath)), m_postFiltering(std::move(postFiltering)), m_sites(std::move(sites)) {} void Favorite::setImagePath(const QString &imagePath) { m_imagePath = imagePath; } void Favorite::setLastViewed(const QDateTime &lastViewed) { m_lastViewed = lastViewed; } +void Favorite::setLastImage(const QString &site, const QVariantMap &lastImage) +{ m_lastImages[site] = lastImage; } void Favorite::setNote(int note) { m_note = note; } void Favorite::setPostFiltering(const QStringList &postFiltering) @@ -93,7 +95,7 @@ Favorite Favorite::fromString(const QString &path, const QString &text) thumbPath = ":/images/noimage.png"; } - return Favorite(tag, note, lastViewed, thumbPath); + return Favorite(tag, note, lastViewed, {}, thumbPath); } void Favorite::toJson(QJsonObject &json) const @@ -123,6 +125,14 @@ void Favorite::toJson(QJsonObject &json) const } json["sites"] = QJsonArray::fromStringList(sites); } + + if (!m_lastImages.isEmpty()) { + QJsonObject lastImages; + for (auto it = m_lastImages.constBegin(); it != m_lastImages.constEnd(); ++it) { + lastImages[it.key()] = QJsonObject::fromVariantMap(it.value()); + } + json["lastImages"] = lastImages; + } } Favorite Favorite::fromJson(const QString &path, const QJsonObject &json, Profile *profile) { @@ -170,7 +180,16 @@ Favorite Favorite::fromJson(const QString &path, const QJsonObject &json, Profil } } - return Favorite(tag, note, lastViewed, monitors, thumbPath, postFiltering, sites); + // Last images + QMap lastImages; + if (json.contains("lastImages")) { + const QJsonObject obj = json["lastImages"].toObject(); + for (auto it = obj.constBegin(); it != obj.constEnd(); ++it) { + lastImages[it.key()] = it.value().toObject().toVariantMap(); + } + } + + return Favorite(tag, note, lastViewed, lastImages, monitors, thumbPath, postFiltering, sites); } bool Favorite::sortByNote(const Favorite &s1, const Favorite &s2) diff --git a/src/lib/src/models/favorite.h b/src/lib/src/models/favorite.h index c5e98ffe7..2a8fe4b82 100644 --- a/src/lib/src/models/favorite.h +++ b/src/lib/src/models/favorite.h @@ -14,17 +14,19 @@ class Favorite { public: explicit Favorite(QString name); - Favorite(QString name, int note, QDateTime lastViewed, QString imagePath = "", QStringList postFiltering = {}, QList sites = {}); - Favorite(QString name, int note, QDateTime lastViewed, QList monitors, QString imagePath = "", QStringList postFiltering = {}, QList sites = {}); + Favorite(QString name, int note, QDateTime lastViewed, QMap lastImages = {}, QString imagePath = "", QStringList postFiltering = {}, QList sites = {}); + Favorite(QString name, int note, QDateTime lastViewed, QMap lastImages, QList monitors, QString imagePath = "", QStringList postFiltering = {}, QList sites = {}); // Getters and setters void setNote(int note); void setLastViewed(const QDateTime &lastViewed); + void setLastImage(const QString &site, const QVariantMap &lastImage); void setImagePath(const QString &imagePath); void setPostFiltering(const QStringList &postFiltering); void setSites(const QList &sites); int getNote() const; QDateTime getLastViewed() const; + QMap getLastImages() const { return m_lastImages; }; QString getImagePath() const; QList &getMonitors(); QStringList getPostFiltering() const; @@ -53,6 +55,7 @@ class Favorite QString m_name; int m_note; QDateTime m_lastViewed; + QMap m_lastImages; QList m_monitors; QString m_imagePath; QStringList m_postFiltering; diff --git a/src/lib/src/models/image.cpp b/src/lib/src/models/image.cpp index dd33499bd..25d61c5f5 100644 --- a/src/lib/src/models/image.cpp +++ b/src/lib/src/models/image.cpp @@ -891,7 +891,13 @@ Site *Image::parentSite() const { return m_parentSite; } const QList &Image::tags() const { return m_tags; } const QList &Image::pools() const { return m_pools; } qulonglong Image::id() const { return m_id; } -QVariantMap Image::identity() const { return m_identity; } +QVariantMap Image::identity(bool id) const +{ + if (m_identity.isEmpty() && id) { + return {{"id", m_id}}; + } + return m_identity; +} int Image::fileSize() const { return m_sizes[Image::Size::Full]->fileSize; } int Image::width() const { return size(Image::Size::Full).width(); } int Image::height() const { return size(Image::Size::Full).height(); } diff --git a/src/lib/src/models/image.h b/src/lib/src/models/image.h index 952dd769f..366cba16a 100644 --- a/src/lib/src/models/image.h +++ b/src/lib/src/models/image.h @@ -54,7 +54,7 @@ class Image : public QObject, public Downloadable QStringList tagsString(bool namespaces = false) const; const QList &pools() const; qulonglong id() const; - QVariantMap identity() const; + QVariantMap identity(bool id = false) const; int fileSize() const; int width() const; int height() const; diff --git a/src/lib/tests/src/models/favorite-test.cpp b/src/lib/tests/src/models/favorite-test.cpp index 4e0a1b073..2c5b96fd2 100644 --- a/src/lib/tests/src/models/favorite-test.cpp +++ b/src/lib/tests/src/models/favorite-test.cpp @@ -74,14 +74,14 @@ TEST_CASE("Favorite") SECTION("GetImagePath") { QDateTime date = QDateTime::fromString("2016-07-02 16:35:12", "yyyy-MM-dd HH:mm:ss"); - Favorite fav("fate/stay_night", 50, date, "test/test.jpg"); + Favorite fav("fate/stay_night", 50, date, {}, "test/test.jpg"); REQUIRE(fav.getImagePath() == QString("test/test.jpg")); } SECTION("SetImagePath") { QDateTime date = QDateTime::fromString("2016-07-02 16:35:12", "yyyy-MM-dd HH:mm:ss"); - Favorite fav("fate/stay_night", 50, date, "test/test.jpg"); + Favorite fav("fate/stay_night", 50, date, {}, "test/test.jpg"); fav.setImagePath("test/newimage.jpg"); REQUIRE(fav.getImagePath() == QString("test/newimage.jpg")); @@ -91,7 +91,7 @@ TEST_CASE("Favorite") { QDateTime date = QDateTime::fromString("2016-07-02 16:35:12", "yyyy-MM-dd HH:mm:ss"); Monitor monitor(QList(), 60, date, date, false, "", ""); - Favorite fav("fate/stay_night", 50, date, QList() << monitor, "test/test.jpg"); + Favorite fav("fate/stay_night", 50, date, {}, QList() << monitor, "test/test.jpg"); fav.setImagePath("test/newimage.jpg"); REQUIRE(fav.getMonitors().count() == 1); @@ -204,7 +204,7 @@ TEST_CASE("Favorite") } QDateTime date = QDateTime::fromString("2016-07-02 16:35:12", "yyyy-MM-dd HH:mm:ss"); - Favorite fav("tag1", 50, date, QDir::currentPath() + "/tests/resources/image_200x200.png"); + Favorite fav("tag1", 50, date, {}, QDir::currentPath() + "/tests/resources/image_200x200.png"); QPixmap actual = fav.getImage(); REQUIRE(file.exists() == true); @@ -290,7 +290,7 @@ TEST_CASE("Favorite") QDateTime date = QDateTime::fromString("2016-07-02 16:35:12", "yyyy-MM-dd HH:mm:ss"); Monitor monitor(QList { &site }, 60, date, date, false, "", ""); - Favorite original("fate/stay_night", 50, date, QList() << monitor); + Favorite original("fate/stay_night", 50, date, {}, QList() << monitor); QJsonObject json; original.toJson(json);