mirror of
https://github.com/immich-app/immich.git
synced 2026-01-20 00:30:54 -08:00
* feat: bring back manual backup * expose iCloud retrieval progress * wip * unify http upload method, check for connectivity on iOS * handle LivePhotos progress * feat: speed calculation * wip * better upload detail page * handle error * handle error * pr feedback * feat: share intent upload * feat: manual upload * feat: manual upload progress * chore: styling * refactor * refactor * remove unused logs * fix: background android backup * feat: add error section * remove complete section * remove empty state and prevent slot jumps * more refactor * fix: background test * chore: add metadata to foreground upload * fix: email and name get reset in auth provider * pr feedback * remove version check for metadata field in upload payload * chore: fix unit test --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
61 lines
1.6 KiB
Swift
61 lines
1.6 KiB
Swift
import Network
|
|
|
|
class ConnectivityApiImpl: ConnectivityApi {
|
|
private let monitor = NWPathMonitor()
|
|
private let queue = DispatchQueue(label: "ConnectivityMonitor")
|
|
private var currentPath: NWPath?
|
|
|
|
init() {
|
|
monitor.pathUpdateHandler = { [weak self] path in
|
|
self?.currentPath = path
|
|
}
|
|
monitor.start(queue: queue)
|
|
// Get initial state synchronously
|
|
currentPath = monitor.currentPath
|
|
}
|
|
|
|
deinit {
|
|
monitor.cancel()
|
|
}
|
|
|
|
func getCapabilities() throws -> [NetworkCapability] {
|
|
guard let path = currentPath else {
|
|
return []
|
|
}
|
|
|
|
guard path.status == .satisfied else {
|
|
return []
|
|
}
|
|
|
|
var capabilities: [NetworkCapability] = []
|
|
|
|
if path.usesInterfaceType(.wifi) {
|
|
capabilities.append(.wifi)
|
|
}
|
|
|
|
if path.usesInterfaceType(.cellular) {
|
|
capabilities.append(.cellular)
|
|
}
|
|
|
|
// Check for VPN - iOS reports VPN as .other interface type in many cases
|
|
// or through the path's expensive property when on cellular with VPN
|
|
if path.usesInterfaceType(.other) {
|
|
capabilities.append(.vpn)
|
|
}
|
|
|
|
// Determine if connection is unmetered:
|
|
// - Must be on WiFi (not cellular)
|
|
// - Must not be expensive (rules out personal hotspot)
|
|
// - Must not be constrained (Low Data Mode)
|
|
// Note: VPN over cellular should still be considered metered
|
|
let isOnCellular = path.usesInterfaceType(.cellular)
|
|
let isOnWifi = path.usesInterfaceType(.wifi)
|
|
|
|
if isOnWifi && !isOnCellular && !path.isExpensive && !path.isConstrained {
|
|
capabilities.append(.unmetered)
|
|
}
|
|
|
|
return capabilities
|
|
}
|
|
}
|