Compare commits
No commits in common. "master" and "v1.0.3" have entirely different histories.
|
|
@ -3,18 +3,7 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# Pastors Sermon Pro 📖✨
|
# Pastors Sermon Pro 📖✨
|
||||||
**Version 1.1.7**
|
**Version 1.0.3**
|
||||||
|
|
||||||
## ✨ What's New in V1.1.7
|
|
||||||
- **Dynamic Theming Engine**: Complete support for Light and Dark modes across all components (Bible Reader, Sermon Builder, Search, etc.).
|
|
||||||
- **Integrated Model Downloader**: Background downloading of AI models from HuggingFace with status bar progress tracking.
|
|
||||||
- **Enhanced Bug Reporting**: Added screenshot capture and automated debug.log attachment for faster troubleshooting.
|
|
||||||
- **Hardware-Aware AI**: Smart recommendations for AI models based on your system's RAM and GPU specs.
|
|
||||||
|
|
||||||
## ✨ What's New in V1.0.7
|
|
||||||
- **Audio Optimization:** Reduced default video volume to 40% to prevent distortion and speaker crackling on some systems.
|
|
||||||
- **Improved Multimedia:** Finalized FFmpeg dependency bundling for stable video playback.
|
|
||||||
- **Enhanced Settings:** Added version tracking and manual update controls.
|
|
||||||
|
|
||||||
## ✨ What's New in V1.0.3
|
## ✨ What's New in V1.0.3
|
||||||
- **Smart Updates:** The app now correctly compares version numbers to only notify you of truly newer updates.
|
- **Smart Updates:** The app now correctly compares version numbers to only notify you of truly newer updates.
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 3.1 MiB After Width: | Height: | Size: 3.1 MiB |
BIN
resources/ai.png
|
Before Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 202 KiB After Width: | Height: | Size: 202 KiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 151 KiB |
|
Before Width: | Height: | Size: 3.1 MiB |
|
|
@ -1,16 +0,0 @@
|
||||||
<RCC>
|
|
||||||
<qresource prefix="/">
|
|
||||||
<file alias="splash.png">../splash.png</file>
|
|
||||||
<file>bible.png</file>
|
|
||||||
<file>search.png</file>
|
|
||||||
<file>sermon.png</file>
|
|
||||||
<file>ai.png</file>
|
|
||||||
<file>library.png</file>
|
|
||||||
<file>setting.png</file>
|
|
||||||
<file alias="help.html">../src/help.html</file>
|
|
||||||
<file>welcome/welcome_1.png</file>
|
|
||||||
<file>welcome/welcome_2.png</file>
|
|
||||||
<file>welcome/welcome_3.png</file>
|
|
||||||
<file>welcome/welcome_4.png</file>
|
|
||||||
</qresource>
|
|
||||||
</RCC>
|
|
||||||
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 1.8 MiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 214 KiB |
|
Before Width: | Height: | Size: 429 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 3.0 MiB After Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 3.2 MiB After Width: | Height: | Size: 3.2 MiB |
|
|
@ -1,121 +0,0 @@
|
||||||
#include "UpdateManager.h"
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QStandardPaths>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QUrl>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
UpdateManager::UpdateManager(const QString& currentVersion, QObject *parent)
|
|
||||||
: QObject(parent), m_currentVersion(currentVersion), m_downloadFile(nullptr)
|
|
||||||
{
|
|
||||||
m_network = new QNetworkAccessManager(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateManager::checkForUpdates() {
|
|
||||||
emit checkStarted();
|
|
||||||
|
|
||||||
QUrl url;
|
|
||||||
if (m_isBeta) {
|
|
||||||
url = QUrl("https://git.linology.tech/michael/Pastors-Sermon-Pro-Bug-Reports/raw/branch/main/version.txt");
|
|
||||||
} else {
|
|
||||||
url = QUrl("https://git.linology.tech/michael/PastorsSermonPro/raw/branch/master/version.txt");
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkRequest request;
|
|
||||||
request.setUrl(url);
|
|
||||||
QNetworkReply* reply = m_network->get(request);
|
|
||||||
connect(reply, &QNetworkReply::finished, this, &UpdateManager::onVersionFetched);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateManager::onVersionFetched() {
|
|
||||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
|
||||||
if (!reply) return;
|
|
||||||
|
|
||||||
if (reply->error() == QNetworkReply::NoError) {
|
|
||||||
m_latestVersion = QString::fromUtf8(reply->readAll()).trimmed();
|
|
||||||
|
|
||||||
// Smart semantic version comparison
|
|
||||||
if (!m_latestVersion.isEmpty() && isNewer(m_currentVersion, m_latestVersion)) {
|
|
||||||
// Construct the download URL for the Windows installer
|
|
||||||
if (m_isBeta) {
|
|
||||||
m_downloadUrl = QString("https://git.linology.tech/michael/Pastors-Sermon-Pro-Bug-Reports/releases/download/v%1/PastorsSermonPro_Setup.exe").arg(m_latestVersion);
|
|
||||||
} else {
|
|
||||||
m_downloadUrl = QString("https://git.linology.tech/michael/PastorsSermonPro/releases/download/v%1/PastorsSermonPro_Setup.exe").arg(m_latestVersion);
|
|
||||||
}
|
|
||||||
emit updateAvailable(m_latestVersion, m_downloadUrl);
|
|
||||||
} else {
|
|
||||||
emit noUpdateFound();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
emit errorOccurred("Could not reach update server: " + reply->errorString());
|
|
||||||
}
|
|
||||||
reply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateManager::startDownload(const QString& url) {
|
|
||||||
m_downloadUrl = url;
|
|
||||||
QString tempPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
|
|
||||||
QString fileName = tempPath + "/PastorsSermonPro_Update.exe";
|
|
||||||
|
|
||||||
m_downloadFile = new QFile(fileName, this);
|
|
||||||
if (!m_downloadFile->open(QIODevice::WriteOnly)) {
|
|
||||||
emit errorOccurred("Could not create temporary file for download.");
|
|
||||||
delete m_downloadFile;
|
|
||||||
m_downloadFile = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QNetworkRequest request;
|
|
||||||
request.setUrl(QUrl(m_downloadUrl));
|
|
||||||
QNetworkReply* reply = m_network->get(request);
|
|
||||||
|
|
||||||
connect(reply, &QNetworkReply::downloadProgress, this, &UpdateManager::onDownloadProgress);
|
|
||||||
connect(reply, &QNetworkReply::finished, this, &UpdateManager::onDownloadFinished);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateManager::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
|
|
||||||
if (bytesTotal > 0) {
|
|
||||||
int percentage = static_cast<int>((bytesReceived * 100) / bytesTotal);
|
|
||||||
emit progressUpdated(percentage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateManager::onDownloadFinished() {
|
|
||||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
|
|
||||||
if (!reply) return;
|
|
||||||
|
|
||||||
if (reply->error() == QNetworkReply::NoError) {
|
|
||||||
m_downloadFile->write(reply->readAll());
|
|
||||||
m_downloadFile->flush();
|
|
||||||
QString filePath = m_downloadFile->fileName();
|
|
||||||
m_downloadFile->close();
|
|
||||||
|
|
||||||
emit downloadFinished(filePath);
|
|
||||||
|
|
||||||
// Launch the installer
|
|
||||||
QProcess::startDetached(filePath);
|
|
||||||
} else {
|
|
||||||
emit errorOccurred("Download failed: " + reply->errorString());
|
|
||||||
m_downloadFile->close();
|
|
||||||
m_downloadFile->remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
reply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UpdateManager::isNewer(const QString& current, const QString& latest) {
|
|
||||||
QStringList curParts = current.split('.');
|
|
||||||
QStringList latParts = latest.split('.');
|
|
||||||
|
|
||||||
int maxLen = std::max(curParts.size(), latParts.size());
|
|
||||||
for (int i = 0; i < maxLen; ++i) {
|
|
||||||
int cur = (i < curParts.size()) ? curParts[i].toInt() : 0;
|
|
||||||
int lat = (i < latParts.size()) ? latParts[i].toInt() : 0;
|
|
||||||
if (lat > cur) return true;
|
|
||||||
if (lat < cur) return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
1.1.8
|
1.0.3
|
||||||
|
|
|
||||||