mirror of
https://github.com/YACReader/yacreader
synced 2025-07-17 20:44:32 -04:00
Add support for storing and serving the new comic filters format
It's already implemented on iOS and next is supporting it on Android.
This commit is contained in:
@ -2,7 +2,7 @@
|
||||
|
||||
Version counting is based on semantic versioning (Major.Feature.Patch)
|
||||
|
||||
## WIP (9.15.1)
|
||||
## WIP (9.16.0)
|
||||
### YACReader
|
||||
* Don't use scroll animations on macos by default, it where hdpi scroll is most likely to be used.
|
||||
* New toolbar on macos.
|
||||
@ -21,6 +21,7 @@ Version counting is based on semantic versioning (Major.Feature.Patch)
|
||||
* Add support for custom covers for comics using the edit metadata dialog, you can use a pick file button or drag&drop an image into the cover view in the dialog.
|
||||
* Covers can be set in bulk for various comics at once.
|
||||
* New button to reset to the default cover of a comic.
|
||||
* Support for storing the new image filters from iOS and Android apps.
|
||||
|
||||
### YACReaderLibraryServer
|
||||
* Log libraries validation when the app starts.
|
||||
|
@ -81,7 +81,13 @@ static QString fields = "title,"
|
||||
"seriesGroup,"
|
||||
"mainCharacterOrTeam,"
|
||||
"review,"
|
||||
"tags";
|
||||
"tags,"
|
||||
// new 9.16 fields
|
||||
"imageFiltersJson,"
|
||||
"lastTimeImageFiltersSet,"
|
||||
"lastTimeCoverSet,"
|
||||
"usesExternalCover,"
|
||||
"lastTimeMetadataSet";
|
||||
|
||||
DataBaseManagement::DataBaseManagement()
|
||||
: QObject(), dataBasesList()
|
||||
@ -284,7 +290,13 @@ bool DataBaseManagement::createComicInfoTable(QSqlDatabase &database, QString ta
|
||||
"seriesGroup TEXT,"
|
||||
"mainCharacterOrTeam TEXT,"
|
||||
"review TEXT,"
|
||||
"tags TEXT"
|
||||
"tags TEXT,"
|
||||
// new 9.16 fields
|
||||
"imageFiltersJson TEXT,"
|
||||
"lastTimeImageFiltersSet INTEGER DEFAULT 0,"
|
||||
"lastTimeCoverSet INTEGER DEFAULT 0,"
|
||||
"usesExternalCover BOOLEAN DEFAULT 0,"
|
||||
"lastTimeMetadataSet INTEGER DEFAULT 0"
|
||||
")");
|
||||
|
||||
return queryComicInfo.exec();
|
||||
@ -862,6 +874,7 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &libraryPath)
|
||||
bool pre9_8 = false;
|
||||
bool pre9_13 = false;
|
||||
bool pre9_14 = false;
|
||||
bool pre9_16 = false;
|
||||
|
||||
QString libraryDatabasePath = LibraryPaths::libraryDatabasePath(libraryPath);
|
||||
|
||||
@ -879,6 +892,8 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &libraryPath)
|
||||
pre9_13 = true;
|
||||
if (compareVersions(DataBaseManagement::checkValidDB(libraryDatabasePath), "9.14.0") < 0)
|
||||
pre9_14 = true;
|
||||
if (compareVersions(DataBaseManagement::checkValidDB(libraryDatabasePath), "9.16.0") < 0)
|
||||
pre9_16 = true;
|
||||
|
||||
QString connectionName = "";
|
||||
bool returnValue = true;
|
||||
@ -1080,6 +1095,22 @@ bool DataBaseManagement::updateToCurrentVersion(const QString &libraryPath)
|
||||
}
|
||||
}
|
||||
|
||||
if (pre9_16) {
|
||||
{ // comic_info
|
||||
QStringList columnDefs;
|
||||
columnDefs << "imageFiltersJson TEXT";
|
||||
columnDefs << "lastTimeImageFiltersSet INTEGER DEFAULT 0";
|
||||
|
||||
columnDefs << "lastTimeCoverSet INTEGER DEFAULT 0";
|
||||
columnDefs << "usesExternalCover BOOLEAN DEFAULT 0";
|
||||
|
||||
columnDefs << "lastTimeMetadataSet INTEGER DEFAULT 0";
|
||||
|
||||
bool successAddingColumns = addColumns("comic_info", columnDefs, db);
|
||||
returnValue = returnValue && successAddingColumns;
|
||||
}
|
||||
}
|
||||
|
||||
if (returnValue) {
|
||||
QSqlQuery updateVersion(db);
|
||||
updateVersion.prepare("UPDATE db_info SET "
|
||||
|
@ -712,7 +712,14 @@ void DBHelper::update(ComicInfo *comicInfo, QSqlDatabase &db)
|
||||
"seriesGroup = :seriesGroup,"
|
||||
"mainCharacterOrTeam = :mainCharacterOrTeam,"
|
||||
"review = :review,"
|
||||
"tags = :tags"
|
||||
"tags = :tags,"
|
||||
|
||||
// new 9.16 fields
|
||||
"imageFiltersJson = :imageFiltersJson,"
|
||||
"lastTimeImageFiltersSet = :lastTimeImageFiltersSet,"
|
||||
"lastTimeCoverSet = :lastTimeCoverSet,"
|
||||
"usesExternalCover = :usesExternalCover,"
|
||||
"lastTimeMetadataSet = :lastTimeMetadataSet"
|
||||
|
||||
//--
|
||||
" WHERE id = :id");
|
||||
@ -790,6 +797,12 @@ void DBHelper::update(ComicInfo *comicInfo, QSqlDatabase &db)
|
||||
updateComicInfo.bindValue(":review", comicInfo->review);
|
||||
updateComicInfo.bindValue(":tags", comicInfo->tags);
|
||||
|
||||
updateComicInfo.bindValue(":imageFiltersJson", comicInfo->imageFiltersJson);
|
||||
updateComicInfo.bindValue(":lastTimeImageFiltersSet", comicInfo->lastTimeImageFiltersSet);
|
||||
updateComicInfo.bindValue(":lastTimeCoverSet", comicInfo->lastTimeCoverSet);
|
||||
updateComicInfo.bindValue(":usesExternalCover", comicInfo->usesExternalCover);
|
||||
updateComicInfo.bindValue(":lastTimeMetadataSet", comicInfo->lastTimeMetadataSet);
|
||||
|
||||
updateComicInfo.exec();
|
||||
|
||||
QLOG_INFO() << updateComicInfo.lastError().databaseText();
|
||||
@ -962,6 +975,41 @@ void DBHelper::updateProgress(qulonglong libraryId, const ComicInfo &comicInfo)
|
||||
QSqlDatabase::removeDatabase(connectionName);
|
||||
}
|
||||
|
||||
void DBHelper::updateImageFilters(qulonglong libraryId, const ComicInfo &comicInfo)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
|
||||
QString connectionName = "";
|
||||
{
|
||||
QSqlDatabase db = DataBaseManagement::loadDatabase(LibraryPaths::libraryDataPath(libraryPath));
|
||||
|
||||
bool found;
|
||||
ComicDB comic = DBHelper::loadComic(comicInfo.id, db, found);
|
||||
|
||||
if (found && comic.info.lastTimeImageFiltersSet.toULongLong() < comicInfo.lastTimeImageFiltersSet.toULongLong()) {
|
||||
QSqlQuery updateComicInfo(db);
|
||||
updateComicInfo.prepare("UPDATE comic_info SET "
|
||||
"lastTimeImageFiltersSet = :lastTimeImageFiltersSet, "
|
||||
"imageFiltersJson = :imageFiltersJson "
|
||||
" WHERE id = :id ");
|
||||
|
||||
updateComicInfo.bindValue(":lastTimeImageFiltersSet", comicInfo.lastTimeImageFiltersSet.toULongLong());
|
||||
updateComicInfo.bindValue(":imageFiltersJson", comicInfo.imageFiltersJson);
|
||||
updateComicInfo.bindValue(":id", comic.info.id);
|
||||
|
||||
auto ret = updateComicInfo.exec();
|
||||
if (!ret) {
|
||||
QLOG_ERROR() << "Error updating image filters for comic ID:" << comicInfo.id;
|
||||
QLOG_ERROR() << updateComicInfo.lastError().databaseText();
|
||||
QLOG_ERROR() << updateComicInfo.lastError().text();
|
||||
}
|
||||
}
|
||||
|
||||
connectionName = db.connectionName();
|
||||
}
|
||||
|
||||
QSqlDatabase::removeDatabase(connectionName);
|
||||
}
|
||||
|
||||
void DBHelper::setComicAsReading(qulonglong libraryId, const ComicInfo &comicInfo)
|
||||
{
|
||||
QString libraryPath = DBHelper::getLibraries().getPath(libraryId);
|
||||
@ -1944,6 +1992,12 @@ ComicInfo DBHelper::getComicInfoFromQuery(QSqlQuery &query, const QString &idKey
|
||||
int review = record.indexOf("review");
|
||||
int tags = record.indexOf("tags");
|
||||
|
||||
int imageFiltersJson = record.indexOf("imageFiltersJson");
|
||||
int lastTimeImageFiltersSet = record.indexOf("lastTimeImageFiltersSet");
|
||||
int lastTimeCoverSet = record.indexOf("lastTimeCoverSet");
|
||||
int usesExternalCover = record.indexOf("usesExternalCover");
|
||||
int lastTimeMetadataSet = record.indexOf("lastTimeMetadataSet");
|
||||
|
||||
ComicInfo comicInfo;
|
||||
|
||||
comicInfo.hash = query.value(hash).toString();
|
||||
@ -2026,6 +2080,14 @@ ComicInfo DBHelper::getComicInfoFromQuery(QSqlQuery &query, const QString &idKey
|
||||
comicInfo.tags = query.value(tags);
|
||||
//--
|
||||
|
||||
// new 9.16 fields
|
||||
comicInfo.imageFiltersJson = query.value(imageFiltersJson);
|
||||
comicInfo.lastTimeImageFiltersSet = query.value(lastTimeImageFiltersSet);
|
||||
comicInfo.lastTimeCoverSet = query.value(lastTimeCoverSet);
|
||||
comicInfo.usesExternalCover = query.value(usesExternalCover).toBool();
|
||||
comicInfo.lastTimeMetadataSet = query.value(lastTimeMetadataSet);
|
||||
//--
|
||||
|
||||
comicInfo.existOnDb = true;
|
||||
|
||||
return comicInfo;
|
||||
|
@ -72,6 +72,7 @@ public:
|
||||
static Folder updateChildrenInfo(qulonglong folderId, QSqlDatabase &db);
|
||||
static void updateChildrenInfo(QSqlDatabase &db);
|
||||
static void updateProgress(qulonglong libraryId, const ComicInfo &comicInfo);
|
||||
static void updateImageFilters(qulonglong libraryId, const ComicInfo &comicInfo);
|
||||
static void setComicAsReading(qulonglong libraryId, const ComicInfo &comicInfo);
|
||||
[[deprecated("Server v1")]] static void updateFromRemoteClient(qulonglong libraryId, const ComicInfo &comicInfo);
|
||||
static void updateReadingRemoteProgress(const ComicInfo &comicInfo, QSqlDatabase &db);
|
||||
|
@ -34,7 +34,6 @@ void UpdateComicControllerV2::service(HttpRequest &request, HttpResponse &respon
|
||||
ComicInfo info;
|
||||
info.currentPage = currentPage;
|
||||
info.id = comicId;
|
||||
DBHelper::updateProgress(libraryId, info);
|
||||
|
||||
if (data.length() > 1) {
|
||||
if (data.at(1).isEmpty() == false) {
|
||||
@ -43,8 +42,23 @@ void UpdateComicControllerV2::service(HttpRequest &request, HttpResponse &respon
|
||||
info.id = nextComicId.toULongLong();
|
||||
DBHelper::setComicAsReading(libraryId, info);
|
||||
}
|
||||
|
||||
if (data.length() > 2) {
|
||||
QStringList imageFiltersData = data.at(2).split("\t");
|
||||
auto epoch = imageFiltersData.at(0).toULongLong();
|
||||
QString imageFiltersJson = imageFiltersData.at(1);
|
||||
|
||||
ComicInfo imageFiltersInfo;
|
||||
imageFiltersInfo.id = comicId;
|
||||
imageFiltersInfo.lastTimeImageFiltersSet = epoch;
|
||||
imageFiltersInfo.imageFiltersJson = imageFiltersJson.isEmpty() ? QVariant() : imageFiltersJson;
|
||||
|
||||
DBHelper::updateImageFilters(libraryId, imageFiltersInfo);
|
||||
}
|
||||
}
|
||||
|
||||
DBHelper::updateProgress(libraryId, info);
|
||||
|
||||
error = false;
|
||||
updatedLibraryId = libraryId;
|
||||
updatedComicId = comicId;
|
||||
|
@ -170,6 +170,12 @@ QJsonObject YACReaderServerDataHelper::fullComicToJSON(const qulonglong libraryI
|
||||
json["brightness"] = comic.info.brightness;
|
||||
json["contrast"] = comic.info.contrast;
|
||||
json["gamma"] = comic.info.gamma;
|
||||
// 9.16
|
||||
variantToJson("image_filters_json", QMetaType::QString, comic.info.imageFiltersJson, json);
|
||||
variantToJson("last_time_image_filters_set", QMetaType::LongLong, comic.info.lastTimeImageFiltersSet, json);
|
||||
variantToJson("last_time_cover_set", QMetaType::LongLong, comic.info.lastTimeCoverSet, json);
|
||||
variantToJson("uses_external_cover", QMetaType::Bool, comic.info.usesExternalCover, json);
|
||||
variantToJson("last_time_metadata_set", QMetaType::LongLong, comic.info.lastTimeMetadataSet, json);
|
||||
|
||||
return json;
|
||||
}
|
||||
|
@ -166,6 +166,23 @@ QString ComicDB::toTXT()
|
||||
if (!info.tags.isNull())
|
||||
txt.append(QString("tags:%1\r\n").arg(info.tags.toString()));
|
||||
|
||||
// 9.16
|
||||
|
||||
if (!info.imageFiltersJson.isNull())
|
||||
txt.append(QString("imageFiltersJson:%1\r\n").arg(info.imageFiltersJson.toString()));
|
||||
|
||||
if (!info.lastTimeImageFiltersSet.isNull())
|
||||
txt.append(QString("lastTimeImageFiltersSet:%1\r\n").arg(info.lastTimeImageFiltersSet.toULongLong()));
|
||||
|
||||
if (!info.lastTimeCoverSet.isNull())
|
||||
txt.append(QString("lastTimeCoverSet:%1\r\n").arg(info.lastTimeCoverSet.toULongLong()));
|
||||
|
||||
if (!info.usesExternalCover.isNull())
|
||||
txt.append(QString("usesExternalCover:%1\r\n").arg(info.usesExternalCover.toBool() ? "1" : "0"));
|
||||
|
||||
if (!info.lastTimeMetadataSet.isNull())
|
||||
txt.append(QString("lastTimeMetadataSet:%1\r\n").arg(info.lastTimeMetadataSet.toULongLong()));
|
||||
|
||||
return txt;
|
||||
}
|
||||
|
||||
@ -399,6 +416,12 @@ ComicInfo &ComicInfo::operator=(const ComicInfo &comicInfo)
|
||||
review = comicInfo.review;
|
||||
tags = comicInfo.tags;
|
||||
|
||||
imageFiltersJson = comicInfo.imageFiltersJson;
|
||||
lastTimeImageFiltersSet = comicInfo.lastTimeImageFiltersSet;
|
||||
lastTimeCoverSet = comicInfo.lastTimeCoverSet;
|
||||
usesExternalCover = comicInfo.usesExternalCover;
|
||||
lastTimeMetadataSet = comicInfo.lastTimeMetadataSet;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -691,6 +714,12 @@ QDataStream &operator<<(QDataStream &stream, const ComicInfo &comicInfo)
|
||||
stream << comicInfo.review;
|
||||
stream << comicInfo.tags;
|
||||
|
||||
stream << comicInfo.imageFiltersJson;
|
||||
stream << comicInfo.lastTimeImageFiltersSet;
|
||||
stream << comicInfo.lastTimeCoverSet;
|
||||
stream << comicInfo.usesExternalCover;
|
||||
stream << comicInfo.lastTimeMetadataSet;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
@ -770,5 +799,11 @@ QDataStream &operator>>(QDataStream &stream, ComicInfo &comicInfo)
|
||||
stream >> comicInfo.review;
|
||||
stream >> comicInfo.tags;
|
||||
|
||||
stream >> comicInfo.imageFiltersJson;
|
||||
stream >> comicInfo.lastTimeImageFiltersSet;
|
||||
stream >> comicInfo.lastTimeCoverSet;
|
||||
stream >> comicInfo.usesExternalCover;
|
||||
stream >> comicInfo.lastTimeMetadataSet;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
@ -39,9 +39,9 @@ public:
|
||||
int bookmark1;
|
||||
int bookmark2;
|
||||
int bookmark3;
|
||||
int brightness;
|
||||
int contrast;
|
||||
int gamma;
|
||||
[[deprecated("Use imageFiltersJson")]] int brightness;
|
||||
[[deprecated("Use imageFiltersJson")]] int contrast;
|
||||
[[deprecated("Use imageFiltersJson")]] int gamma;
|
||||
//-----------------
|
||||
|
||||
QVariant title; // string
|
||||
@ -104,6 +104,12 @@ public:
|
||||
QVariant review; // string
|
||||
QVariant tags; // string/list
|
||||
|
||||
QVariant imageFiltersJson; // string, JSON with image filters
|
||||
QVariant lastTimeImageFiltersSet; // integer/date, last time image filters were set
|
||||
QVariant lastTimeCoverSet; // integer/date, last time cover was set
|
||||
QVariant usesExternalCover; // bool, whether the cover is external or not
|
||||
QVariant lastTimeMetadataSet; // integer/date, last time metadata was set
|
||||
|
||||
QPixmap getCover(const QString &basePath);
|
||||
|
||||
Q_INVOKABLE QStringList getWriters();
|
||||
@ -208,6 +214,12 @@ public:
|
||||
Q_PROPERTY(QVariant review MEMBER review CONSTANT)
|
||||
Q_PROPERTY(QVariant tags MEMBER tags CONSTANT)
|
||||
|
||||
Q_PROPERTY(QVariant imageFiltersJson MEMBER imageFiltersJson CONSTANT)
|
||||
Q_PROPERTY(QVariant lastTimeImageFiltersSet MEMBER lastTimeImageFiltersSet CONSTANT)
|
||||
Q_PROPERTY(QVariant lastTimeCoverSet MEMBER lastTimeCoverSet CONSTANT)
|
||||
Q_PROPERTY(QVariant usesExternalCover MEMBER usesExternalCover CONSTANT)
|
||||
Q_PROPERTY(QVariant lastTimeMetadataSet MEMBER lastTimeMetadataSet CONSTANT)
|
||||
|
||||
//-new properties, not loaded from the DB automatically
|
||||
bool isFavorite;
|
||||
Q_PROPERTY(bool isFavorite MEMBER isFavorite WRITE setFavorite NOTIFY favoriteChanged)
|
||||
|
@ -9,11 +9,11 @@
|
||||
|
||||
class QLibrary;
|
||||
|
||||
#define VERSION "9.15.1"
|
||||
#define VERSION "9.16.0"
|
||||
|
||||
// Used to check if the database needs to be updated, the version is stored in the database.
|
||||
// This value is only incremented when the database structure changes.
|
||||
#define DB_VERSION "9.14.0"
|
||||
#define DB_VERSION "9.16.0"
|
||||
|
||||
#define IMPORT_COMIC_INFO_XML_METADATA "IMPORT_COMIC_INFO_XML_METADATA"
|
||||
#define COMPARE_MODIFIED_DATE_ON_LIBRARY_UPDATES "COMPARE_MODIFIED_DATE_ON_LIBRARY_UPDATES"
|
||||
|
@ -43,42 +43,31 @@ YACReader::WhatsNewDialog::WhatsNewDialog(QWidget *parent)
|
||||
versionLabel->setAlignment(Qt::AlignCenter);
|
||||
versionLabel->setStyleSheet("padding:0 0 0 0;"
|
||||
"background-color:transparent;"
|
||||
"color:#858585;");
|
||||
|
||||
auto text = new QLabel();
|
||||
text->setText("This version brings new features, improved functionality, enhanced customization options, bug fixes, and performance improvements across all apps: <br/>"
|
||||
"color:#858585;"); auto text = new QLabel();
|
||||
text->setText("This version brings exciting new features, improved functionality, enhanced customization options, bug fixes, and performance improvements across all apps: <br/>"
|
||||
"<br/>"
|
||||
"<span style=\"font-weight:600\">YACReader</span><br/>"
|
||||
" • Save magnifying glass size and zoom level<br/>"
|
||||
" • Add shortcut to reset the magnifying glass to its defaults (size and zoom), it is `slash` by default but it can be reassigned<br/>"
|
||||
" • Bump PDF render size<br/>"
|
||||
" • Fix trackpad scrolling, it makes using trackpads more responsive and natural<br/>"
|
||||
" • Added more info to Help -> System info<br/>"
|
||||
" • Don't use scroll animations on macos by default, it where hdpi scroll is most likely to be used and it causes scroll issues. (new 9.15.1)<br/>"
|
||||
" • Don't use scroll animations on macOS by default, where hdpi scroll is most likely to be used<br/>"
|
||||
" • New toolbar on macOS<br/>"
|
||||
" • New mouse modes to turn pages - you can setup the app to use the left/right buttons to turn pages directly or click on the left/right part of the screen to turn pages<br/>"
|
||||
"<br/>"
|
||||
"<span style=\"font-weight:600\">YACReaderLibrary</span><br/>"
|
||||
" • Fix headers in the table view getting stuck in a non-movable state<br/>"
|
||||
" • Add option to set the type of a library. It will convert all the content to the desired type (comic, manga, etc.) and set that type as the default for the library. Available in the library context menu<br/>"
|
||||
" • Added more info to Help -> System info<br/>"
|
||||
" • New setting to open comics in third-party reader apps by entering a command that launches the app, e.g., \"/path/to/the/app {comic_file_path}\". Use `{comic_file_path}` as a placeholder where `YACReaderLibrary` places the path to the comic file<br/>"
|
||||
" • Purge covers and metadata not being used after a full library update<br/>"
|
||||
" • Fix crash when updating the current folder content after a library update<br/>"
|
||||
" • Fix crash when current folder is empty after an update<br/>"
|
||||
" • Enable dropping content on the FolderContentView<br/>"
|
||||
" • Fix `open containing folder...` shortcut for comics<br/>"
|
||||
" • Add a dialog to show information about a library, including the number of folders, comics, and read comics<br/>"
|
||||
" • Fix occasional crashes when using automatic library updates<br/>"
|
||||
" • Add setting to hide the \"Continue Reading...\" banner from the home view<br/>"
|
||||
" • Improve Grid and Flow Info comics view scroll performance<br/>"
|
||||
" • Improve flexibility of the open comic in third party app setting so more complex commands can be used. e.g. `open -a \"/Applications/My Reader.app"
|
||||
"{comic_file_path}\"` (new 9.15.1)<br/>"
|
||||
" • Improve flexibility of the open comic in third party app setting so more complex commands can be used, e.g. `open -a \"/Applications/My Reader.app\" \"{comic_file_path}\"`<br/>"
|
||||
" • Fix setting the comic rating in the table view<br/>"
|
||||
" • Log libraries validation when the app starts<br/>"
|
||||
" • New toolbar on macOS<br/>"
|
||||
" • New setting in Comic Vine scraper to force exact volume matches<br/>"
|
||||
" • Better default search query in the Comic Vine scraper<br/>"
|
||||
" • Improved navigation in Comic Vine scraper, including keeping the current query around to make edits and refined searches easier<br/>"
|
||||
" • Add support for custom covers for any folder using the context menu<br/>"
|
||||
" • The edit cover buttons now support looping through pages, going forward from the last returns to the first, and going backward from the first jumps to the last<br/>"
|
||||
" • Add support for custom covers for comics using the edit metadata dialog, you can use a pick file button or drag&drop an image into the cover view in the dialog<br/>"
|
||||
" • Covers can be set in bulk for various comics at once<br/>"
|
||||
" • New button to reset to the default cover of a comic<br/>"
|
||||
" • Support for storing the new image filters from iOS and Android apps<br/>"
|
||||
"<br/>"
|
||||
"<span style=\"font-weight:600\">YACReaderLibraryServer</span><br/>"
|
||||
" • New command --system-info to print information about the execution environment and available resources (including what image formats are supported and what libraries are used by the app).<br/>"
|
||||
" • Fix automatic libraries updates not being triggered.<br/>"
|
||||
"<br/>"
|
||||
"<span style=\"font-weight:600\">All apps</span><br/>"
|
||||
" • Sorting heuristic to try to find spreads in the content of a comic is now only used for files with less than 1000 pages to avoid false positives.<br/>"
|
||||
" • Log libraries validation when the app starts<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> "
|
||||
"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. "
|
||||
|
Reference in New Issue
Block a user