Skip to content

Commit

Permalink
feat: store last favorite image ID in addition to date (fix #1058)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bionus committed May 5, 2024
1 parent cbd91e5 commit bc5c833
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 24 deletions.
4 changes: 4 additions & 0 deletions src/gui/src/favorite-window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,14 @@ void FavoriteWindow::save()
monitors[0] = rep;
}

// Only keep the last images if the "last viewed" datetime is unchanged
const QMap<QString, QVariantMap> lastImages = oldFav.getLastViewed() == ui->lastViewedDateTimeEdit->dateTime() ? oldFav.getLastImages() : QMap<QString, QVariantMap>();

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),
Expand Down
31 changes: 24 additions & 7 deletions src/gui/src/tabs/favorites-tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Image> &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
Expand Down Expand Up @@ -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()) {
Expand Down Expand Up @@ -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<Image> &img)
{
log(QStringLiteral("Marking \"%1\" as viewed...").arg(tag));

Expand All @@ -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();
Expand Down Expand Up @@ -414,7 +431,7 @@ void FavoritesTab::thumbnailContextMenu(QMenu *menu, const QSharedPointer<Image>
{
SearchTab::thumbnailContextMenu(menu, img);

if (m_currentTags.isEmpty() || !img->createdAt().isValid()) {
if (m_currentTags.isEmpty()) {
return;
}

Expand All @@ -423,7 +440,7 @@ void FavoritesTab::thumbnailContextMenu(QMenu *menu, const QSharedPointer<Image>
// 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);

Expand Down
3 changes: 2 additions & 1 deletion src/gui/src/tabs/favorites-tab.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Image> &img = {});
void viewed();
// Others
void closeEvent(QCloseEvent *event) override;
Expand All @@ -61,6 +61,7 @@ class FavoritesTab : public SearchTab
QDateTime m_loadFavorite;
QString m_currentTags;
int m_currentFav;
QMap<QString, QVariantMap> m_lastImages, m_newLastImages;
FixedSizeGridLayout *m_favoritesLayout;
};

Expand Down
33 changes: 26 additions & 7 deletions src/lib/src/models/favorite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Site*> sites)
: Favorite(std::move(name), note, std::move(lastViewed), QList<Monitor>(), std::move(imagePath), std::move(postFiltering), std::move(sites))
Favorite::Favorite(QString name, int note, QDateTime lastViewed, QMap<QString, QVariantMap> lastImages, QString imagePath, QStringList postFiltering, QList<Site*> sites)
: Favorite(std::move(name), note, std::move(lastViewed), std::move(lastImages), QList<Monitor>(), std::move(imagePath), std::move(postFiltering), std::move(sites))
{}
Favorite::Favorite(QString name, int note, QDateTime lastViewed, QList<Monitor> monitors, QString imagePath, QStringList postFiltering, QList<Site*> 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<QString, QVariantMap> lastImages, QList<Monitor> monitors, QString imagePath, QStringList postFiltering, QList<Site*> 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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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<QString, QVariantMap> 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)
Expand Down
7 changes: 5 additions & 2 deletions src/lib/src/models/favorite.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,19 @@ class Favorite
{
public:
explicit Favorite(QString name);
Favorite(QString name, int note, QDateTime lastViewed, QString imagePath = "", QStringList postFiltering = {}, QList<Site*> sites = {});
Favorite(QString name, int note, QDateTime lastViewed, QList<Monitor> monitors, QString imagePath = "", QStringList postFiltering = {}, QList<Site*> sites = {});
Favorite(QString name, int note, QDateTime lastViewed, QMap<QString, QVariantMap> lastImages = {}, QString imagePath = "", QStringList postFiltering = {}, QList<Site*> sites = {});
Favorite(QString name, int note, QDateTime lastViewed, QMap<QString, QVariantMap> lastImages, QList<Monitor> monitors, QString imagePath = "", QStringList postFiltering = {}, QList<Site*> 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<Site*> &sites);
int getNote() const;
QDateTime getLastViewed() const;
QMap<QString, QVariantMap> getLastImages() const { return m_lastImages; };
QString getImagePath() const;
QList<Monitor> &getMonitors();
QStringList getPostFiltering() const;
Expand Down Expand Up @@ -53,6 +55,7 @@ class Favorite
QString m_name;
int m_note;
QDateTime m_lastViewed;
QMap<QString, QVariantMap> m_lastImages;
QList<Monitor> m_monitors;
QString m_imagePath;
QStringList m_postFiltering;
Expand Down
8 changes: 7 additions & 1 deletion src/lib/src/models/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,13 @@ Site *Image::parentSite() const { return m_parentSite; }
const QList<Tag> &Image::tags() const { return m_tags; }
const QList<Pool> &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(); }
Expand Down
2 changes: 1 addition & 1 deletion src/lib/src/models/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Image : public QObject, public Downloadable
QStringList tagsString(bool namespaces = false) const;
const QList<Pool> &pools() const;
qulonglong id() const;
QVariantMap identity() const;
QVariantMap identity(bool id = false) const;
int fileSize() const;
int width() const;
int height() const;
Expand Down
10 changes: 5 additions & 5 deletions src/lib/tests/src/models/favorite-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand All @@ -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<Site*>(), 60, date, date, false, "", "");
Favorite fav("fate/stay_night", 50, date, QList<Monitor>() << monitor, "test/test.jpg");
Favorite fav("fate/stay_night", 50, date, {}, QList<Monitor>() << monitor, "test/test.jpg");
fav.setImagePath("test/newimage.jpg");

REQUIRE(fav.getMonitors().count() == 1);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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*> { &site }, 60, date, date, false, "", "");
Favorite original("fate/stay_night", 50, date, QList<Monitor>() << monitor);
Favorite original("fate/stay_night", 50, date, {}, QList<Monitor>() << monitor);

QJsonObject json;
original.toJson(json);
Expand Down

0 comments on commit bc5c833

Please sign in to comment.