Add Recent list.

This commit is contained in:
Luis Ángel San Martín
2023-06-03 16:45:47 +02:00
parent 2ff723bcd0
commit 864516d781
9 changed files with 86 additions and 11 deletions

View File

@ -7,7 +7,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch)
### YACReaderLibrary
* Avoid showing stale information in the server config dialog by updating the connection information when the dialog is opened.
* Add new metadata support, it improves compatibility with ComicInfo.xml
* Add support for showing a "recently added/updated" indicator.
* Add support for showing a "recently added/updated" indicator. The number of days to consider something recent can be configured in the settings.
* Improved comic metadata dialog.
* Add textual tags support that can be queried through the search engine.
* Make = in the search engine work as : does.
@ -15,6 +15,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch)
* Support filtering by since/before dates in the search engine. e.g. `added > 7` means recent content added since 7 days ago, and `added < 30` means content added before the last 30 days.
* Show the full library path in the dialog shown to warn about missing libraries.
* Fix scroll bar in the info comics view in Qt6 builds.
* New `Recent` smart list, it will show recent comics added.
### All Apps
* New icons for macos.

View File

@ -623,6 +623,36 @@ void ComicModel::setupReadingModelData(const QString &databasePath)
endResetModel();
}
void ComicModel::setupRecentModelData(const QString &databasePath)
{
enableResorting = false;
mode = Recent;
sourceId = -1;
beginResetModel();
qDeleteAll(_data);
_data.clear();
_databasePath = databasePath;
QString connectionName = "";
{
QSqlDatabase db = DataBaseManagement::loadDatabase(databasePath);
QSqlQuery selectQuery(db);
selectQuery.prepare("SELECT " COMIC_MODEL_QUERY_FIELDS " "
"FROM comic c INNER JOIN comic_info ci ON (c.comicInfoId = ci.id) "
"WHERE ci.added > :limit "
"ORDER BY ci.added DESC");
selectQuery.bindValue(":limit", QDateTime::currentDateTime().addDays(-recentDays).toSecsSinceEpoch());
selectQuery.exec();
setupModelDataForList(selectQuery);
connectionName = db.connectionName();
}
QSqlDatabase::removeDatabase(connectionName);
endResetModel();
}
void ComicModel::setModelData(QList<ComicItem *> *data, const QString &databasePath)
{
_databasePath = databasePath;
@ -923,6 +953,9 @@ void ComicModel::reload()
case Reading:
setupReadingModelData(_databasePath);
break;
case Recent:
setupRecentModelData(_databasePath);
break;
case Label:
setupLabelModelData(sourceId, _databasePath);
break;
@ -1155,6 +1188,9 @@ void ComicModel::setRecentRange(int days)
this->recentDays = days;
emit dataChanged(index(0, 0), index(rowCount() - 1, 0), { ComicModel::RecentRangeRole });
if (mode == ComicModel::Recent)
reload();
}
void ComicModel::updateRating(int rating, QModelIndex mi)

View File

@ -67,6 +67,7 @@ public:
Folder,
Favorites,
Reading,
Recent,
Label,
ReadingList
};
@ -96,6 +97,7 @@ public:
void setupReadingListModelData(unsigned long long int parentReadingList, const QString &databasePath);
void setupFavoritesModelData(const QString &databasePath);
void setupReadingModelData(const QString &databasePath);
void setupRecentModelData(const QString &databasePath);
// Métodos de conveniencia
QStringList getPaths(const QString &_source);

View File

@ -82,7 +82,7 @@ QVariant ReadingListModel::data(const QModelIndex &index, int role) const
if (role == ReadingListModel::SpecialListTypeRole && typeid(*item) == typeid(SpecialListItem)) {
auto specialListItem = static_cast<SpecialListItem *>(item);
return QVariant(specialListItem->getType());
return QVariant::fromValue(specialListItem->getType());
}
if (typeid(*item) == typeid(ReadingListSeparatorItem))
@ -196,7 +196,10 @@ bool ReadingListModel::canDropMimeData(const QMimeData *data, Qt::DropAction act
if (row == -1) // no list
return false;
if (row == 1) // reading is just an smart list
if (row == 1) // reading is just a smart list
return false;
if (row == 2) // recent is just a smart list
return false;
if (rowIsSeparator(row, parent))
@ -609,8 +612,8 @@ QList<SpecialListItem *> ReadingListModel::setupSpecialLists(QSqlDatabase &db)
<< selectQuery.value(id));
}
// Reading after Favorites, Why? Because I want to :P
list.insert(1, new SpecialListItem(QList<QVariant>() << "Reading" << 0));
list.insert(2, new SpecialListItem(QList<QVariant>() << "Recent" << 2));
return list;
}

View File

@ -69,9 +69,10 @@ public:
Separator
};
enum TypeSpecialList {
Reading,
Favorites
enum class TypeSpecialList : int {
Reading = 0,
Favorites,
Recent,
};
signals:

View File

@ -96,6 +96,8 @@
<file>../images/lists/default_0.svg</file>
<file>../images/lists/default_1.svg</file>
<file>../images/lists/default_2.svg</file>
<file>../images/lists/label_blue.svg</file>
<file>../images/lists/label_cyan.svg</file>
<file>../images/lists/label_dark.svg</file>

View File

@ -102,12 +102,15 @@ void YACReaderNavigationController::loadSpecialListInfo(const QModelIndex &model
ReadingListModel::TypeSpecialList type = (ReadingListModel::TypeSpecialList)modelIndex.data(ReadingListModel::SpecialListTypeRole).toInt();
switch (type) {
case ReadingListModel::Favorites:
case ReadingListModel::TypeSpecialList::Favorites:
libraryWindow->comicsModel->setupFavoritesModelData(libraryWindow->foldersModel->getDatabase());
break;
case ReadingListModel::Reading:
case ReadingListModel::TypeSpecialList::Reading:
libraryWindow->comicsModel->setupReadingModelData(libraryWindow->foldersModel->getDatabase());
break;
case ReadingListModel::TypeSpecialList::Recent:
libraryWindow->comicsModel->setupRecentModelData(libraryWindow->foldersModel->getDatabase());
break;
}
contentViewsManager->comicsView->setModel(libraryWindow->comicsModel);
@ -118,14 +121,18 @@ void YACReaderNavigationController::loadSpecialListInfo(const QModelIndex &model
} else {
// setup empty special list widget
switch (type) {
case ReadingListModel::Favorites:
case ReadingListModel::TypeSpecialList::Favorites:
contentViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_favorites.png"));
contentViewsManager->emptySpecialList->setText(tr("No favorites"));
break;
case ReadingListModel::Reading:
case ReadingListModel::TypeSpecialList::Reading:
contentViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_current_readings.png"));
contentViewsManager->emptySpecialList->setText(tr("You are not reading anything yet, come on!!"));
break;
case ReadingListModel::TypeSpecialList::Recent:
contentViewsManager->emptySpecialList->setPixmap(QPixmap());
contentViewsManager->emptySpecialList->setText(tr("There are no recent comics!"));
break;
}
contentViewsManager->showEmptySpecialList();

View File

@ -56,6 +56,10 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent)
" &#8226; Add textual tags support that can be queried through the search engine.<br/>"
" &#8226; Make '=' in the search engine work as ':' does.<br/>"
" &#8226; Add new operators to the search engine: exact match ==, <, >, <=, >=.<br/>"
" &#8226; Support filtering by since/before dates in the search engine. e.g. `added > 7` means recent content added since 7 days ago, and `added < 30` means content added before the last 30 days."
" &#8226; Show the full library path in the dialog shown to warn about missing libraries."
" &#8226; Fix scroll bar in the info comics view in Qt6 builds."
" &#8226; New `Recent` smart list, it will show recent comics added."
"<br/>"
"I hope you enjoy the new update. Please, if you like YACReader consider to become a patron in <a href=\"https://www.patreon.com/yacreader\" style=\"color:#E8B800;\">Patreon</a> "
"or donate some money using <a href=\"https://www.paypal.com/donate?business=5TAMNQCDDMVP8&item_name=Support+YACReader\" style=\"color:#E8B800;\">Pay-Pal</a> and help keeping the project alive. "

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<defs>
<style>
.cls-1 {
opacity: .24;
}
.cls-2 {
fill: #fc0;
}
</style>
</defs>
<g class="cls-1">
<circle cx="7.5" cy="7.5" r="6.79"/>
</g>
<circle cx="7.5" cy="8.5" r="3.29"/>
<circle class="cls-2" cx="7.5" cy="7.5" r="3.29"/>
</svg>

After

Width:  |  Height:  |  Size: 432 B