Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Scribe.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
073976D82F7C5EF3004F0674 /* NetworkMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 073976D72F7C5EF3004F0674 /* NetworkMonitor.swift */; };
140158992A430DD000D14E52 /* ThirdPartyLicense.swift in Sources */ = {isa = PBXBuildFile; fileRef = 140158982A430DD000D14E52 /* ThirdPartyLicense.swift */; };
1401589B2A45A07200D14E52 /* WikimediaAndScribe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1401589A2A45A07200D14E52 /* WikimediaAndScribe.swift */; };
140158A22A4EDB2200D14E52 /* TableViewTemplateViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 140158A12A4EDB2200D14E52 /* TableViewTemplateViewController.swift */; };
Expand Down Expand Up @@ -1015,6 +1016,7 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
073976D72F7C5EF3004F0674 /* NetworkMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkMonitor.swift; sourceTree = "<group>"; };
140158982A430DD000D14E52 /* ThirdPartyLicense.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartyLicense.swift; sourceTree = "<group>"; };
1401589A2A45A07200D14E52 /* WikimediaAndScribe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WikimediaAndScribe.swift; sourceTree = "<group>"; };
140158A12A4EDB2200D14E52 /* TableViewTemplateViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewTemplateViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2051,6 +2053,7 @@
children = (
EDEE62242B2DE65A00A0B9C1 /* UIEdgeInsetsExtensions.swift */,
84AF4D872C3575EA009AE0D2 /* UIDeviceExtensions.swift */,
073976D72F7C5EF3004F0674 /* NetworkMonitor.swift */,
);
path = Extensions;
sourceTree = "<group>";
Expand Down Expand Up @@ -2925,6 +2928,7 @@
D16DD3A529E78A1500FB9022 /* Utilities.swift in Sources */,
EDB460212B03B3E400BEA967 /* BaseTableViewController.swift in Sources */,
D1CDED752A859DDD00098546 /* DAInterfaceVariables.swift in Sources */,
073976D82F7C5EF3004F0674 /* NetworkMonitor.swift in Sources */,
84AF4D882C3575EA009AE0D2 /* UIDeviceExtensions.swift in Sources */,
69B81EBC2BFB8C77008CAB85 /* TipCardView.swift in Sources */,
30453964293B9D18003AE55B /* InformationToolTipData.swift in Sources */,
Expand Down
20 changes: 20 additions & 0 deletions Scribe/Extensions/NetworkMonitor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: GPL-3.0-or-later

import Network

/// Lightweight singleton that tracks network reachability using NWPathMonitor.
final class NetworkMonitor {
static let shared = NetworkMonitor()

private let monitor = NWPathMonitor()
private let queue = DispatchQueue(label: "be.scri.networkMonitor", qos: .utility)

private(set) var isConnected: Bool = true

private init() {
monitor.pathUpdateHandler = { [weak self] path in
self?.isConnected = path.status == .satisfied
}
monitor.start(queue: queue)
}
}
22 changes: 22 additions & 0 deletions Scribe/InstallationTab/DownloadStateManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ class DownloadStateManager: ObservableObject {
let currentState = downloadStates[key] ?? .ready
let displayName = getKeyInDict(givenValue: key, dict: languagesAbbrDict)

// Block if offline.
guard NetworkMonitor.shared.isConnected else {
showToastMessage(
NSLocalizedString(
"i18n.app.download.error.no_internet",
value: "No internet connection. Please connect and try again.",
comment: ""
)
)
return
}

// Block if already downloading.
if currentState == .downloading {
return
Expand Down Expand Up @@ -102,6 +114,16 @@ class DownloadStateManager: ObservableObject {

/// Check all downloaded languages for updates.
func checkAllForUpdates() {
guard NetworkMonitor.shared.isConnected else {
showToastMessage(
NSLocalizedString(
"i18n.app.download.error.no_internet",
value: "No internet connection. Please connect and try again.",
comment: ""
)
)
return
}
for (language, state) in downloadStates where state == .updated {
checkForUpdates(language: language)
}
Expand Down
Loading