diff --git a/src/audiomanager.cpp b/src/audiomanager.cpp index f4342338..16e2a393 100644 --- a/src/audiomanager.cpp +++ b/src/audiomanager.cpp @@ -389,19 +389,25 @@ void AudioManager::play() // connection if (isStreaming()) { if (!NetworkConnectionManager::instance().streamingAllowed()) { - qCDebug(kastsAudio) << "Refusing to play: no connection or streaming on metered connection not allowed"; - QString feedUrl, entryId; - if (d->m_entry) { - feedUrl = d->m_entry->feed()->url(); - entryId = d->m_entry->id(); + if (NetworkConnectionManager::instance().networkReachable()) { + qCDebug(kastsAudio) << "Refusing to play: streaming on metered connection not allowed"; + QString feedUrl, entryId; + if (d->m_entry) { + feedUrl = d->m_entry->feed()->url(); + entryId = d->m_entry->id(); + } + Q_EMIT logError(Error::Type::MeteredStreamingNotAllowed, feedUrl, entryId, 0, i18n("Streaming on metered connection not allowed"), QString()); + return; + } else { + qCDebug(kastsAudio) << "Refusing to play: no network connection"; + QString feedUrl, entryId; + if (d->m_entry) { + feedUrl = d->m_entry->feed()->url(); + entryId = d->m_entry->id(); + } + Q_EMIT logError(Error::Type::NoNetwork, feedUrl, entryId, 0, i18n("No network connection"), QString()); + return; } - Q_EMIT logError(Error::Type::MeteredStreamingNotAllowed, - feedUrl, - entryId, - 0, - i18n("No connection or streaming on metered connection not allowed"), - QString()); - return; } } diff --git a/src/enclosure.cpp b/src/enclosure.cpp index 906e1fb2..4c384f9d 100644 --- a/src/enclosure.cpp +++ b/src/enclosure.cpp @@ -156,13 +156,18 @@ void Enclosure::download() } if (!NetworkConnectionManager::instance().episodeDownloadsAllowed()) { - Q_EMIT downloadError(Error::Type::MeteredNotAllowed, - m_entry->feed()->url(), - m_entry->id(), - 0, - i18n("Podcast downloads not allowed due to user setting"), - QString()); - return; + if (NetworkConnectionManager::instance().networkReachable()) { + Q_EMIT downloadError(Error::Type::MeteredNotAllowed, + m_entry->feed()->url(), + m_entry->id(), + 0, + i18n("Podcast downloads not allowed on metered connection"), + QString()); + return; + } else { + Q_EMIT downloadError(Error::Type::NoNetwork, m_entry->feed()->url(), m_entry->id(), 0, i18n("No network connection"), QString()); + return; + } } checkSizeOnDisk(); diff --git a/src/error.cpp b/src/error.cpp index ea347ff4..dbcd3a3e 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -59,7 +59,9 @@ QString Error::description() const case Error::Type::SyncError: return i18n("Error syncing feed and/or episode status"); case Error::Type::MeteredStreamingNotAllowed: - return i18n("Connection or streaming not allowed on metered connection"); + return i18n("Streaming not allowed on metered connection"); + case Error::Type::NoNetwork: + return i18n("No network connection"); default: return QString(); } @@ -84,6 +86,8 @@ int Error::typeToDb(Error::Type type) return 6; case Error::Type::MeteredStreamingNotAllowed: return 7; + case Error::Type::NoNetwork: + return 8; default: return -1; } @@ -108,6 +112,8 @@ Error::Type Error::dbToType(int value) return Error::Type::SyncError; case 7: return Error::Type::MeteredStreamingNotAllowed; + case 8: + return Error::Type::NoNetwork; default: return Error::Type::Unknown; } diff --git a/src/error.h b/src/error.h index bc3481e7..95d9de89 100644 --- a/src/error.h +++ b/src/error.h @@ -25,6 +25,7 @@ public: StorageMoveError, SyncError, MeteredStreamingNotAllowed, + NoNetwork, }; Q_ENUM(Type) diff --git a/src/qml/ConnectionCheckAction.qml b/src/qml/ConnectionCheckAction.qml index 5859abbc..9f4a182e 100644 --- a/src/qml/ConnectionCheckAction.qml +++ b/src/qml/ConnectionCheckAction.qml @@ -18,7 +18,7 @@ Kirigami.Dialog { parent: applicationWindow().overlay closePolicy: Kirigami.Dialog.CloseOnEscape | Kirigami.Dialog.CloseOnPressOutside - property string headingText: i18n("Podcast updates are currently not allowed on metered connections") + property string headingText: i18nc("@info:status", "Podcast updates are currently not allowed on metered connections") property bool condition: NetworkConnectionManager.feedUpdatesAllowed // Function to be overloaded where this is instantiated with another purpose @@ -52,7 +52,7 @@ Kirigami.Dialog { } } - title: i18n("Select Option") + title: NetworkConnectionManager.networkReachable ? i18nc("@title:window", "Select Option") : i18nc("@title:window", "Network not reachable") ColumnLayout { spacing: 0 @@ -63,17 +63,19 @@ Kirigami.Dialog { Layout.leftMargin: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing Layout.rightMargin: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing Layout.fillWidth: true - text: headingText + text: NetworkConnectionManager.networkReachable ? headingText : i18nc("@info:status", "It seems the network cannot be reached. If this is incorrect, this check can be disabled through: Settings > Network.") wrapMode: Text.Wrap - color: Kirigami.Theme.disabledTextColor + color: NetworkConnectionManager.networkReachable ?Kirigami.Theme.disabledTextColor : Kirigami.Theme.textColor } Kirigami.Separator { + visible: NetworkConnectionManager.networkReachable Layout.fillWidth: true opacity: 0.5 } Delegates.RoundedItemDelegate { + visible: NetworkConnectionManager.networkReachable Layout.fillWidth: true Layout.preferredHeight: Kirigami.Units.gridUnit * 2 leftPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing @@ -87,6 +89,7 @@ Kirigami.Dialog { } Delegates.RoundedItemDelegate { + visible: NetworkConnectionManager.networkReachable Layout.fillWidth: true Layout.preferredHeight: Kirigami.Units.gridUnit * 2 leftPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing @@ -100,6 +103,7 @@ Kirigami.Dialog { } Delegates.RoundedItemDelegate { + visible: NetworkConnectionManager.networkReachable Layout.fillWidth: true Layout.preferredHeight: Kirigami.Units.gridUnit * 2 leftPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing diff --git a/src/qml/Settings/NetworkSettingsPage.qml b/src/qml/Settings/NetworkSettingsPage.qml index 86f3307d..f1dc75e6 100644 --- a/src/qml/Settings/NetworkSettingsPage.qml +++ b/src/qml/Settings/NetworkSettingsPage.qml @@ -17,6 +17,25 @@ import org.kde.kasts FormCard.FormCardPage { id: root + FormCard.FormHeader { + Layout.fillWidth: true + title: i18n("Network") + } + + FormCard.FormCard { + Layout.fillWidth: true + + FormCard.FormCheckDelegate { + id: doNetworkChecks + checked: SettingsManager.checkNetworkStatus + text: i18n("Enable network connection checks") + onToggled: { + SettingsManager.checkNetworkStatus = checked; + SettingsManager.save(); + } + } + } + FormCard.FormHeader { Layout.fillWidth: true title: i18n("On metered connections") @@ -27,6 +46,7 @@ FormCard.FormCardPage { FormCard.FormCheckDelegate { id: allowMeteredFeedUpdates + enabled: SettingsManager.checkNetworkStatus checked: SettingsManager.allowMeteredFeedUpdates text: i18n("Allow podcast updates") onToggled: { @@ -37,6 +57,7 @@ FormCard.FormCardPage { FormCard.FormCheckDelegate { id: allowMeteredEpisodeDownloads + enabled: SettingsManager.checkNetworkStatus checked: SettingsManager.allowMeteredEpisodeDownloads text: i18n("Allow episode downloads") onToggled: { @@ -47,6 +68,7 @@ FormCard.FormCardPage { FormCard.FormCheckDelegate { id: allowMeteredImageDownloads + enabled: SettingsManager.checkNetworkStatus checked: SettingsManager.allowMeteredImageDownloads text: i18n("Allow image downloads") onToggled: { @@ -57,6 +79,7 @@ FormCard.FormCardPage { FormCard.FormCheckDelegate { id: allowMeteredStreaming + enabled: SettingsManager.checkNetworkStatus checked: SettingsManager.allowMeteredStreaming text: i18n("Allow streaming") onToggled: { diff --git a/src/qml/main.qml b/src/qml/main.qml index 9972ed31..4dfe5bfb 100644 --- a/src/qml/main.qml +++ b/src/qml/main.qml @@ -429,7 +429,7 @@ Kirigami.ApplicationWindow { ConnectionCheckAction { id: downloadOverlay - headingText: i18n("Podcast downloads are currently not allowed on metered connections") + headingText: i18nc("@info:status", "Podcast downloads are currently not allowed on metered connections") condition: NetworkConnectionManager.episodeDownloadsAllowed property var entry: undefined property var selection: undefined diff --git a/src/settingsmanager.kcfg b/src/settingsmanager.kcfg index 7f126e21..fbdd0335 100644 --- a/src/settingsmanager.kcfg +++ b/src/settingsmanager.kcfg @@ -144,6 +144,10 @@ + + + true + false diff --git a/src/utils/networkconnectionmanager.cpp b/src/utils/networkconnectionmanager.cpp index 89a8572d..fe6f2906 100644 --- a/src/utils/networkconnectionmanager.cpp +++ b/src/utils/networkconnectionmanager.cpp @@ -18,12 +18,14 @@ NetworkConnectionManager::NetworkConnectionManager(QObject *parent) if (m_backendAvailable) { connect(QNetworkInformation::instance(), &QNetworkInformation::reachabilityChanged, this, [this]() { + Q_EMIT networkReachableChanged(); Q_EMIT feedUpdatesAllowedChanged(); Q_EMIT episodeDownloadsAllowedChanged(); Q_EMIT imageDownloadsAllowedChanged(); Q_EMIT streamingAllowedChanged(); }); connect(QNetworkInformation::instance(), &QNetworkInformation::isMeteredChanged, this, [this]() { + Q_EMIT networkReachableChanged(); Q_EMIT feedUpdatesAllowedChanged(); Q_EMIT episodeDownloadsAllowedChanged(); Q_EMIT imageDownloadsAllowedChanged(); @@ -31,18 +33,40 @@ NetworkConnectionManager::NetworkConnectionManager(QObject *parent) }); } + connect(SettingsManager::self(), &SettingsManager::checkNetworkStatusChanged, this, [this]() { + Q_EMIT networkReachableChanged(); + Q_EMIT feedUpdatesAllowedChanged(); + Q_EMIT episodeDownloadsAllowedChanged(); + Q_EMIT imageDownloadsAllowedChanged(); + Q_EMIT streamingAllowedChanged(); + }); + connect(SettingsManager::self(), &SettingsManager::allowMeteredFeedUpdatesChanged, this, &NetworkConnectionManager::feedUpdatesAllowedChanged); connect(SettingsManager::self(), &SettingsManager::allowMeteredEpisodeDownloadsChanged, this, &NetworkConnectionManager::episodeDownloadsAllowedChanged); connect(SettingsManager::self(), &SettingsManager::allowMeteredImageDownloadsChanged, this, &NetworkConnectionManager::imageDownloadsAllowedChanged); connect(SettingsManager::self(), &SettingsManager::allowMeteredStreamingChanged, this, &NetworkConnectionManager::streamingAllowedChanged); } +bool NetworkConnectionManager::networkReachable() const +{ + bool reachable = true; + if (m_backendAvailable) { + reachable = (QNetworkInformation::instance()->reachability() != QNetworkInformation::Reachability::Disconnected + || !SettingsManager::self()->checkNetworkStatus()); + } + + qCDebug(kastsNetworkConnectionManager) << "networkReachable()" << reachable; + + return reachable; +} + bool NetworkConnectionManager::feedUpdatesAllowed() const { bool allowed = true; if (m_backendAvailable) { - allowed = (QNetworkInformation::instance()->reachability() != QNetworkInformation::Reachability::Disconnected - && (!QNetworkInformation::instance()->isMetered() || SettingsManager::self()->allowMeteredFeedUpdates())); + allowed = (networkReachable() + && (!QNetworkInformation::instance()->isMetered() || SettingsManager::self()->allowMeteredFeedUpdates() + || !SettingsManager::self()->checkNetworkStatus())); } qCDebug(kastsNetworkConnectionManager) << "FeedUpdatesAllowed()" << allowed; @@ -54,8 +78,9 @@ bool NetworkConnectionManager::episodeDownloadsAllowed() const { bool allowed = true; if (m_backendAvailable) { - allowed = (QNetworkInformation::instance()->reachability() != QNetworkInformation::Reachability::Disconnected - && (!QNetworkInformation::instance()->isMetered() || SettingsManager::self()->allowMeteredEpisodeDownloads())); + allowed = (networkReachable() + && (!QNetworkInformation::instance()->isMetered() || SettingsManager::self()->allowMeteredEpisodeDownloads() + || !SettingsManager::self()->checkNetworkStatus())); } qCDebug(kastsNetworkConnectionManager) << "EpisodeDownloadsAllowed()" << allowed; @@ -67,8 +92,9 @@ bool NetworkConnectionManager::imageDownloadsAllowed() const { bool allowed = true; if (m_backendAvailable) { - allowed = (QNetworkInformation::instance()->reachability() != QNetworkInformation::Reachability::Disconnected - && (!QNetworkInformation::instance()->isMetered() || SettingsManager::self()->allowMeteredImageDownloads())); + allowed = (networkReachable() + && (!QNetworkInformation::instance()->isMetered() || SettingsManager::self()->allowMeteredImageDownloads() + || !SettingsManager::self()->checkNetworkStatus())); } qCDebug(kastsNetworkConnectionManager) << "ImageDownloadsAllowed()" << allowed; @@ -80,8 +106,9 @@ bool NetworkConnectionManager::streamingAllowed() const { bool allowed = true; if (m_backendAvailable) { - allowed = (QNetworkInformation::instance()->reachability() != QNetworkInformation::Reachability::Disconnected - && (!QNetworkInformation::instance()->isMetered() || SettingsManager::self()->allowMeteredStreaming())); + allowed = (networkReachable() + && (!QNetworkInformation::instance()->isMetered() || SettingsManager::self()->allowMeteredStreaming() + || !SettingsManager::self()->checkNetworkStatus())); } qCDebug(kastsNetworkConnectionManager) << "StreamingAllowed()" << allowed; diff --git a/src/utils/networkconnectionmanager.h b/src/utils/networkconnectionmanager.h index 13bf889d..13a039a1 100644 --- a/src/utils/networkconnectionmanager.h +++ b/src/utils/networkconnectionmanager.h @@ -12,6 +12,7 @@ class NetworkConnectionManager : public QObject { Q_OBJECT + Q_PROPERTY(bool networkReachable READ networkReachable NOTIFY networkReachableChanged) Q_PROPERTY(bool feedUpdatesAllowed READ feedUpdatesAllowed NOTIFY feedUpdatesAllowedChanged) Q_PROPERTY(bool episodeDownloadsAllowed READ episodeDownloadsAllowed NOTIFY episodeDownloadsAllowedChanged) Q_PROPERTY(bool imageDownloadsAllowed READ imageDownloadsAllowed NOTIFY imageDownloadsAllowedChanged) @@ -24,12 +25,14 @@ public: return _instance; } + [[nodiscard]] bool networkReachable() const; [[nodiscard]] bool feedUpdatesAllowed() const; [[nodiscard]] bool episodeDownloadsAllowed() const; [[nodiscard]] bool imageDownloadsAllowed() const; [[nodiscard]] bool streamingAllowed() const; Q_SIGNALS: + void networkReachableChanged(); void feedUpdatesAllowedChanged(); void episodeDownloadsAllowedChanged(); void imageDownloadsAllowedChanged();