mirror of
https://github.com/YACReader/yacreader
synced 2025-07-16 03:54:34 -04:00
Add Recent
list.
This commit is contained in:
@ -7,7 +7,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch)
|
|||||||
### YACReaderLibrary
|
### YACReaderLibrary
|
||||||
* Avoid showing stale information in the server config dialog by updating the connection information when the dialog is opened.
|
* 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 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.
|
* Improved comic metadata dialog.
|
||||||
* Add textual tags support that can be queried through the search engine.
|
* Add textual tags support that can be queried through the search engine.
|
||||||
* Make = in the search engine work as : does.
|
* 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.
|
* 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.
|
* 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.
|
* Fix scroll bar in the info comics view in Qt6 builds.
|
||||||
|
* New `Recent` smart list, it will show recent comics added.
|
||||||
|
|
||||||
### All Apps
|
### All Apps
|
||||||
* New icons for macos.
|
* New icons for macos.
|
||||||
|
@ -623,6 +623,36 @@ void ComicModel::setupReadingModelData(const QString &databasePath)
|
|||||||
endResetModel();
|
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)
|
void ComicModel::setModelData(QList<ComicItem *> *data, const QString &databasePath)
|
||||||
{
|
{
|
||||||
_databasePath = databasePath;
|
_databasePath = databasePath;
|
||||||
@ -923,6 +953,9 @@ void ComicModel::reload()
|
|||||||
case Reading:
|
case Reading:
|
||||||
setupReadingModelData(_databasePath);
|
setupReadingModelData(_databasePath);
|
||||||
break;
|
break;
|
||||||
|
case Recent:
|
||||||
|
setupRecentModelData(_databasePath);
|
||||||
|
break;
|
||||||
case Label:
|
case Label:
|
||||||
setupLabelModelData(sourceId, _databasePath);
|
setupLabelModelData(sourceId, _databasePath);
|
||||||
break;
|
break;
|
||||||
@ -1155,6 +1188,9 @@ void ComicModel::setRecentRange(int days)
|
|||||||
this->recentDays = days;
|
this->recentDays = days;
|
||||||
|
|
||||||
emit dataChanged(index(0, 0), index(rowCount() - 1, 0), { ComicModel::RecentRangeRole });
|
emit dataChanged(index(0, 0), index(rowCount() - 1, 0), { ComicModel::RecentRangeRole });
|
||||||
|
|
||||||
|
if (mode == ComicModel::Recent)
|
||||||
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComicModel::updateRating(int rating, QModelIndex mi)
|
void ComicModel::updateRating(int rating, QModelIndex mi)
|
||||||
|
@ -67,6 +67,7 @@ public:
|
|||||||
Folder,
|
Folder,
|
||||||
Favorites,
|
Favorites,
|
||||||
Reading,
|
Reading,
|
||||||
|
Recent,
|
||||||
Label,
|
Label,
|
||||||
ReadingList
|
ReadingList
|
||||||
};
|
};
|
||||||
@ -96,6 +97,7 @@ public:
|
|||||||
void setupReadingListModelData(unsigned long long int parentReadingList, const QString &databasePath);
|
void setupReadingListModelData(unsigned long long int parentReadingList, const QString &databasePath);
|
||||||
void setupFavoritesModelData(const QString &databasePath);
|
void setupFavoritesModelData(const QString &databasePath);
|
||||||
void setupReadingModelData(const QString &databasePath);
|
void setupReadingModelData(const QString &databasePath);
|
||||||
|
void setupRecentModelData(const QString &databasePath);
|
||||||
|
|
||||||
// Métodos de conveniencia
|
// Métodos de conveniencia
|
||||||
QStringList getPaths(const QString &_source);
|
QStringList getPaths(const QString &_source);
|
||||||
|
@ -82,7 +82,7 @@ QVariant ReadingListModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
if (role == ReadingListModel::SpecialListTypeRole && typeid(*item) == typeid(SpecialListItem)) {
|
if (role == ReadingListModel::SpecialListTypeRole && typeid(*item) == typeid(SpecialListItem)) {
|
||||||
auto specialListItem = static_cast<SpecialListItem *>(item);
|
auto specialListItem = static_cast<SpecialListItem *>(item);
|
||||||
return QVariant(specialListItem->getType());
|
return QVariant::fromValue(specialListItem->getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeid(*item) == typeid(ReadingListSeparatorItem))
|
if (typeid(*item) == typeid(ReadingListSeparatorItem))
|
||||||
@ -196,7 +196,10 @@ bool ReadingListModel::canDropMimeData(const QMimeData *data, Qt::DropAction act
|
|||||||
if (row == -1) // no list
|
if (row == -1) // no list
|
||||||
return false;
|
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;
|
return false;
|
||||||
|
|
||||||
if (rowIsSeparator(row, parent))
|
if (rowIsSeparator(row, parent))
|
||||||
@ -609,8 +612,8 @@ QList<SpecialListItem *> ReadingListModel::setupSpecialLists(QSqlDatabase &db)
|
|||||||
<< selectQuery.value(id));
|
<< selectQuery.value(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reading after Favorites, Why? Because I want to :P
|
|
||||||
list.insert(1, new SpecialListItem(QList<QVariant>() << "Reading" << 0));
|
list.insert(1, new SpecialListItem(QList<QVariant>() << "Reading" << 0));
|
||||||
|
list.insert(2, new SpecialListItem(QList<QVariant>() << "Recent" << 2));
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -69,9 +69,10 @@ public:
|
|||||||
Separator
|
Separator
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TypeSpecialList {
|
enum class TypeSpecialList : int {
|
||||||
Reading,
|
Reading = 0,
|
||||||
Favorites
|
Favorites,
|
||||||
|
Recent,
|
||||||
};
|
};
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -96,6 +96,8 @@
|
|||||||
|
|
||||||
<file>../images/lists/default_0.svg</file>
|
<file>../images/lists/default_0.svg</file>
|
||||||
<file>../images/lists/default_1.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_blue.svg</file>
|
||||||
<file>../images/lists/label_cyan.svg</file>
|
<file>../images/lists/label_cyan.svg</file>
|
||||||
<file>../images/lists/label_dark.svg</file>
|
<file>../images/lists/label_dark.svg</file>
|
||||||
|
@ -102,12 +102,15 @@ void YACReaderNavigationController::loadSpecialListInfo(const QModelIndex &model
|
|||||||
ReadingListModel::TypeSpecialList type = (ReadingListModel::TypeSpecialList)modelIndex.data(ReadingListModel::SpecialListTypeRole).toInt();
|
ReadingListModel::TypeSpecialList type = (ReadingListModel::TypeSpecialList)modelIndex.data(ReadingListModel::SpecialListTypeRole).toInt();
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ReadingListModel::Favorites:
|
case ReadingListModel::TypeSpecialList::Favorites:
|
||||||
libraryWindow->comicsModel->setupFavoritesModelData(libraryWindow->foldersModel->getDatabase());
|
libraryWindow->comicsModel->setupFavoritesModelData(libraryWindow->foldersModel->getDatabase());
|
||||||
break;
|
break;
|
||||||
case ReadingListModel::Reading:
|
case ReadingListModel::TypeSpecialList::Reading:
|
||||||
libraryWindow->comicsModel->setupReadingModelData(libraryWindow->foldersModel->getDatabase());
|
libraryWindow->comicsModel->setupReadingModelData(libraryWindow->foldersModel->getDatabase());
|
||||||
break;
|
break;
|
||||||
|
case ReadingListModel::TypeSpecialList::Recent:
|
||||||
|
libraryWindow->comicsModel->setupRecentModelData(libraryWindow->foldersModel->getDatabase());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
contentViewsManager->comicsView->setModel(libraryWindow->comicsModel);
|
contentViewsManager->comicsView->setModel(libraryWindow->comicsModel);
|
||||||
@ -118,14 +121,18 @@ void YACReaderNavigationController::loadSpecialListInfo(const QModelIndex &model
|
|||||||
} else {
|
} else {
|
||||||
// setup empty special list widget
|
// setup empty special list widget
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ReadingListModel::Favorites:
|
case ReadingListModel::TypeSpecialList::Favorites:
|
||||||
contentViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_favorites.png"));
|
contentViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_favorites.png"));
|
||||||
contentViewsManager->emptySpecialList->setText(tr("No favorites"));
|
contentViewsManager->emptySpecialList->setText(tr("No favorites"));
|
||||||
break;
|
break;
|
||||||
case ReadingListModel::Reading:
|
case ReadingListModel::TypeSpecialList::Reading:
|
||||||
contentViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_current_readings.png"));
|
contentViewsManager->emptySpecialList->setPixmap(QPixmap(":/images/empty_current_readings.png"));
|
||||||
contentViewsManager->emptySpecialList->setText(tr("You are not reading anything yet, come on!!"));
|
contentViewsManager->emptySpecialList->setText(tr("You are not reading anything yet, come on!!"));
|
||||||
break;
|
break;
|
||||||
|
case ReadingListModel::TypeSpecialList::Recent:
|
||||||
|
contentViewsManager->emptySpecialList->setPixmap(QPixmap());
|
||||||
|
contentViewsManager->emptySpecialList->setText(tr("There are no recent comics!"));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
contentViewsManager->showEmptySpecialList();
|
contentViewsManager->showEmptySpecialList();
|
||||||
|
@ -56,6 +56,10 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent)
|
|||||||
" • Add textual tags support that can be queried through the search engine.<br/>"
|
" • Add textual tags support that can be queried through the search engine.<br/>"
|
||||||
" • Make '=' in the search engine work as ':' does.<br/>"
|
" • Make '=' in the search engine work as ':' does.<br/>"
|
||||||
" • Add new operators to the search engine: exact match ==, <, >, <=, >=.<br/>"
|
" • Add new operators to the search engine: exact match ==, <, >, <=, >=.<br/>"
|
||||||
|
" • 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."
|
||||||
"<br/>"
|
"<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> "
|
"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. "
|
"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. "
|
||||||
|
19
images/lists/default_2.svg
Normal file
19
images/lists/default_2.svg
Normal 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 |
Reference in New Issue
Block a user