From 2b0ce47f2297ab49656911eb7d12e6adb71d8929 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 16 Jul 2025 15:54:53 -0700 Subject: [PATCH] Fixing linting errors caused by the bens --- Meshtastic.xcodeproj/project.pbxproj | 4 +- .../xcschemes/Meshtastic.xcscheme | 2 +- .../xcschemes/WidgetsExtension.xcscheme | 2 +- .../AppIntents/FactoryResetNodeIntent.swift | 2 - Meshtastic/AppIntents/RestartNodeIntent.swift | 1 - .../AppIntents/SendWaypointIntent.swift | 4 +- Meshtastic/Extensions/UserDefaults.swift | 5 +- Meshtastic/Helpers/BLEManager.swift | 3 - Meshtastic/Helpers/ContactURLHandler.swift | 4 - Meshtastic/MeshtasticApp.swift | 2 - Meshtastic/MeshtasticAppDelegate.swift | 6 +- Meshtastic/Persistence/UpdateCoreData.swift | 1 - Meshtastic/Views/Helpers/ChannelLock.swift | 7 +- Meshtastic/Views/Messages/MessageText.swift | 78 ++++++++----------- .../Views/Nodes/Helpers/NodeDetail.swift | 39 ++-------- Meshtastic/Views/Settings/Channels.swift | 1 - .../Views/Settings/SaveChannelQRCode.swift | 23 ------ 17 files changed, 54 insertions(+), 130 deletions(-) diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 54a3aa75..7d6f5b32 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -1295,7 +1295,7 @@ attributes = { BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1540; - LastUpgradeCheck = 1630; + LastUpgradeCheck = 1640; TargetAttributes = { 25F5D5C62C4375A8008036E3 = { CreatedOnToolsVersion = 15.4; @@ -1713,6 +1713,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; @@ -1778,6 +1779,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; diff --git a/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme b/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme index 53ea5ca7..50dc8316 100644 --- a/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme +++ b/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme @@ -1,6 +1,6 @@ some IntentResult { - if !BLEManager.shared.isConnected { throw AppIntentErrors.AppIntentError.notConnected } diff --git a/Meshtastic/AppIntents/SendWaypointIntent.swift b/Meshtastic/AppIntents/SendWaypointIntent.swift index fb0f97c3..ba589ee6 100644 --- a/Meshtastic/AppIntents/SendWaypointIntent.swift +++ b/Meshtastic/AppIntents/SendWaypointIntent.swift @@ -11,7 +11,7 @@ import AppIntents import MeshtasticProtobufs struct SendWaypointIntent: AppIntent { - + var defaultDate = Date.now.addingTimeInterval(60 * 480) static var title = LocalizedStringResource("Send a Waypoint") @@ -83,11 +83,9 @@ struct SendWaypointIntent: AppIntent { newWaypoint.icon = unicode newWaypoint.name = name newWaypoint.description_p = description - if let expirationDate = expiration { newWaypoint.expire = UInt32(expirationDate.timeIntervalSince1970) } - if isLocked { if let connectedPeripheral = BLEManager.shared.connectedPeripheral { newWaypoint.lockedTo = UInt32(connectedPeripheral.num) diff --git a/Meshtastic/Extensions/UserDefaults.swift b/Meshtastic/Extensions/UserDefaults.swift index 0b124ac5..a8f550e7 100644 --- a/Meshtastic/Extensions/UserDefaults.swift +++ b/Meshtastic/Extensions/UserDefaults.swift @@ -158,12 +158,13 @@ extension UserDefaults { @UserDefault(.mapReportingOptIn, defaultValue: false) static var mapReportingOptIn: Bool - + @UserDefault(.usageDataAndCrashReporting, defaultValue: true) static var usageDataAndCrashReporting: Bool + @UserDefault(.firstLaunch, defaultValue: true) static var firstLaunch: Bool - + @UserDefault(.showDeviceOnboarding, defaultValue: false) static var showDeviceOnboarding: Bool diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 9d3fdc33..3c50bd26 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -1142,8 +1142,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate sendWantConfig() } - - // MARK: Share Location Position Update Timer // Use context to pass the radio name with the timer // Use a RunLoop to prevent the timer from running on the main UI thread @@ -1159,7 +1157,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate if decodedInfo.configCompleteID != 0 && decodedInfo.configCompleteID == NONCE_ONLY_DB { Logger.mesh.info("🤜 [BLE] Want Config DB Complete. ID:\(decodedInfo.configCompleteID, privacy: .public)") } - case FROMNUM_UUID: Logger.services.info("🗞️ [BLE] (Notify) characteristic value will be read next") default: diff --git a/Meshtastic/Helpers/ContactURLHandler.swift b/Meshtastic/Helpers/ContactURLHandler.swift index 749c8cbf..68334fc0 100644 --- a/Meshtastic/Helpers/ContactURLHandler.swift +++ b/Meshtastic/Helpers/ContactURLHandler.swift @@ -11,15 +11,11 @@ import TipKit import MeshtasticProtobufs struct ContactURLHandler { - static var minimumContactVersion = "2.6.9" - - static func handleContactUrl(url: URL, bleManager: BLEManager) { let supportedVersion = UserDefaults.firmwareVersion == "0.0.0" || minimumContactVersion.compare(UserDefaults.firmwareVersion, options: .numeric) == .orderedAscending || minimumContactVersion.compare(UserDefaults.firmwareVersion, options: .numeric) == .orderedSame - if !supportedVersion { let alertController = UIAlertController( title: "Firmware Upgrade Required", diff --git a/Meshtastic/MeshtasticApp.swift b/Meshtastic/MeshtasticApp.swift index d4de2bf7..19a001e1 100644 --- a/Meshtastic/MeshtasticApp.swift +++ b/Meshtastic/MeshtasticApp.swift @@ -46,9 +46,7 @@ struct MeshtasticAppleApp: App { trackingConsent: UserDefaults.usageDataAndCrashReporting ? .granted : .notGranted, ) DatadogCrashReporting.CrashReporting.enable() - Logs.enable() - Trace.enable( with: Trace.Configuration( sampleRate: 100, networkInfoEnabled: true // 100% sampling for development/testing, reduce for production diff --git a/Meshtastic/MeshtasticAppDelegate.swift b/Meshtastic/MeshtasticAppDelegate.swift index 0c7ada6e..bfa2ed1e 100644 --- a/Meshtastic/MeshtasticAppDelegate.swift +++ b/Meshtastic/MeshtasticAppDelegate.swift @@ -50,7 +50,7 @@ class MeshtasticAppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificat case "messageNotification.thumbsUpAction": if let channel = userInfo["channel"] as? Int32, let replyID = userInfo["messageId"] as? Int64 { - let tapbackResponse = !BLEManager.shared.sendMessage ( + let tapbackResponse = !BLEManager.shared.sendMessage( message: Tapbacks.thumbsUp.emojiString, toUserNum: userInfo["userNum"] as? Int64 ?? 0, channel: channel, @@ -64,7 +64,7 @@ class MeshtasticAppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificat case "messageNotification.thumbsDownAction": if let channel = userInfo["channel"] as? Int32, let replyID = userInfo["messageId"] as? Int64 { - let tapbackResponse = !BLEManager.shared.sendMessage ( + let tapbackResponse = !BLEManager.shared.sendMessage( message: Tapbacks.thumbsDown.emojiString, toUserNum: userInfo["userNum"] as? Int64 ?? 0, channel: channel, @@ -79,7 +79,7 @@ class MeshtasticAppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificat if let userInput = (response as? UNTextInputNotificationResponse)?.userText, let channel = userInfo["channel"] as? Int32, let replyID = userInfo["messageId"] as? Int64 { - let tapbackResponse = !BLEManager.shared.sendMessage ( + let tapbackResponse = !BLEManager.shared.sendMessage( message: userInput, toUserNum: userInfo["userNum"] as? Int64 ?? 0, channel: channel, diff --git a/Meshtastic/Persistence/UpdateCoreData.swift b/Meshtastic/Persistence/UpdateCoreData.swift index 63f9efbc..3c762a49 100644 --- a/Meshtastic/Persistence/UpdateCoreData.swift +++ b/Meshtastic/Persistence/UpdateCoreData.swift @@ -1369,7 +1369,6 @@ func upsertRangeTestModuleConfigPacket(config: ModuleConfig.RangeTestConfig, nod do { try context.save() Logger.data.info("💾 [RangeTestConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)") - } catch { context.rollback() let nsError = error as NSError diff --git a/Meshtastic/Views/Helpers/ChannelLock.swift b/Meshtastic/Views/Helpers/ChannelLock.swift index 3a66dc5a..2621311a 100644 --- a/Meshtastic/Views/Helpers/ChannelLock.swift +++ b/Meshtastic/Views/Helpers/ChannelLock.swift @@ -7,19 +7,18 @@ import SwiftUI struct ChannelLock: View { - + @ObservedObject var channel: ChannelEntity - var body: some View { /// Unencrypted - using no key at all or a known 1 byte key if channel.psk?.hexDescription.count ?? 0 < 3 { let preciseLoction = 17...32 // Using precise location and have MQTT uplink enabled - if channel.uplinkEnabled && preciseLoction ~= (Int(channel.positionPrecision)) { + if channel.uplinkEnabled && preciseLoction ~= (Int(channel.positionPrecision)) { Image(systemName: "lock.open.trianglebadge.exclamationmark.fill") .foregroundColor(.red) // Using precise location - } else if preciseLoction ~= (Int(channel.positionPrecision)) { + } else if preciseLoction ~= (Int(channel.positionPrecision)) { Image(systemName: "lock.open.fill") .foregroundColor(.red) // Just unencrypted without any location or MQTT diff --git a/Meshtastic/Views/Messages/MessageText.swift b/Meshtastic/Views/Messages/MessageText.swift index ac033b1f..b93f413f 100644 --- a/Meshtastic/Views/Messages/MessageText.swift +++ b/Meshtastic/Views/Messages/MessageText.swift @@ -10,9 +10,7 @@ struct MessageText: View { locale: Locale.current ) static let dateFormatString = (localeDateFormat ?? "MM/dd/YY j:mm:ss:a") - @Environment(\.managedObjectContext) var context - let message: MessageEntity let tapBackDestination: MessageDestination let isCurrentUser: Bool @@ -21,7 +19,6 @@ struct MessageText: View { @State private var saveChannels = false @State private var channelSettings: String? @State private var addChannels = false - @State private var isShowingDeleteConfirmation = false var body: some View { @@ -41,10 +38,10 @@ struct MessageText: View { HStack { Spacer() Image(systemName: "lock.circle.fill") - .symbolRenderingMode(.palette) - .foregroundStyle(.white, .green) - .font(.system(size: 20)) - .offset(x: 8, y: 8) + .symbolRenderingMode(.palette) + .foregroundStyle(.white, .green) + .font(.system(size: 20)) + .offset(x: 8, y: 8) } } } @@ -56,10 +53,10 @@ struct MessageText: View { HStack { Spacer() Image(systemName: "envelope.circle.fill") - .symbolRenderingMode(.palette) - .foregroundStyle(.white, .gray) - .font(.system(size: 20)) - .offset(x: 8, y: 8) + .symbolRenderingMode(.palette) + .foregroundStyle(.white, .gray) + .font(.system(size: 20)) + .offset(x: 8, y: 8) } } } @@ -89,39 +86,32 @@ struct MessageText: View { } .environment(\.openURL, OpenURLAction { url in channelSettings = nil - - if url.absoluteString.lowercased().contains("meshtastic.org/v/#") { - // Handle contact URL - ContactURLHandler.handleContactUrl(url: url, bleManager: BLEManager.shared) - return .handled // Prevent default browser opening - } else if url.absoluteString.lowercased().contains("meshtastic.org/e/") { - // Handle channel URL - let components = url.absoluteString.components(separatedBy: "#") - guard !components.isEmpty, let lastComponent = components.last else { - Logger.services.error("No valid components found in channel URL: \(url.absoluteString, privacy: .public)") - return .discarded - } - - self.addChannels = Bool(url.query?.contains("add=true") ?? false) - guard let lastComponent = components.last else { - Logger.services.error("Channel URL missing fragment component: \(url.absoluteString, privacy: .public)") - self.channelSettings = nil - return .discarded - } - - self.channelSettings = lastComponent.components(separatedBy: "?").first ?? "" - - - Logger.services.debug("Add Channel: \(self.addChannels, privacy: .public)") - self.saveChannels = true - Logger.mesh.debug("Opening Channel Settings URL: \(url.absoluteString, privacy: .public)") - return .handled // Prevent default browser opening - } - - return .systemAction // Open other URLs in browser -}) - - // Display sheet for channel settings + if url.absoluteString.lowercased().contains("meshtastic.org/v/#") { + // Handle contact URL + ContactURLHandler.handleContactUrl(url: url, bleManager: BLEManager.shared) + return .handled // Prevent default browser opening + } else if url.absoluteString.lowercased().contains("meshtastic.org/e/") { + // Handle channel URL + let components = url.absoluteString.components(separatedBy: "#") + guard !components.isEmpty, let lastComponent = components.last else { + Logger.services.error("No valid components found in channel URL: \(url.absoluteString, privacy: .public)") + return .discarded + } + self.addChannels = Bool(url.query?.contains("add=true") ?? false) + guard let lastComponent = components.last else { + Logger.services.error("Channel URL missing fragment component: \(url.absoluteString, privacy: .public)") + self.channelSettings = nil + return .discarded + } + self.channelSettings = lastComponent.components(separatedBy: "?").first ?? "" + Logger.services.debug("Add Channel: \(self.addChannels, privacy: .public)") + self.saveChannels = true + Logger.mesh.debug("Opening Channel Settings URL: \(url.absoluteString, privacy: .public)") + return .handled // Prevent default browser opening + } + return .systemAction // Open other URLs in browser + }) + // Display sheet for channel settings .sheet(isPresented: Binding( get: { saveChannels && !(channelSettings == nil) diff --git a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift index d98941bb..24835516 100644 --- a/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift +++ b/Meshtastic/Views/Nodes/Helpers/NodeDetail.swift @@ -19,22 +19,17 @@ struct NodeDetail: View { var modemPreset: ModemPresets = ModemPresets( rawValue: UserDefaults.modemPreset ) ?? ModemPresets.longFast - @Environment(\.managedObjectContext) var context @EnvironmentObject var bleManager: BLEManager @State private var showingShutdownConfirm: Bool = false @State private var showingRebootConfirm: Bool = false @State private var dateFormatRelative: Bool = true - // The node the device is currently connected to var connectedNode: NodeInfoEntity? - // The node information being displayed on the detail screen @ObservedObject var node: NodeInfoEntity - var columnVisibility = NavigationSplitViewVisibility.all - var body: some View { NavigationStack { List { @@ -42,7 +37,6 @@ struct NodeDetail: View { id: bleManager.connectedPeripheral?.num ?? -1, context: context ) - Section("Hardware") { NodeInfoItem(node: node) } @@ -106,10 +100,9 @@ struct NodeDetail: View { } Spacer() Text(String(node.num)) - .textSelection(.enabled) + .textSelection(.enabled) } .accessibilityElement(children: .combine) - HStack { Label { Text("User Id") @@ -119,10 +112,9 @@ struct NodeDetail: View { } Spacer() Text(node.num.toHex()) - .textSelection(.enabled) + .textSelection(.enabled) } .accessibilityElement(children: .combine) - if node.user?.keyMatch ?? false { if let publicKey = node.user?.publicKey { HStack { @@ -134,7 +126,7 @@ struct NodeDetail: View { } Spacer() Button(action: { - context.perform{ + context.perform { UIPasteboard.general.string = publicKey.base64EncodedString() } }) { @@ -147,7 +139,6 @@ struct NodeDetail: View { .accessibilityElement(children: .combine) } } - if let metadata = node.metadata { HStack { Label { @@ -157,12 +148,10 @@ struct NodeDetail: View { .symbolRenderingMode(.multicolor) } Spacer() - Text(metadata.firmwareVersion ?? "Unknown".localized) } .accessibilityElement(children: .combine) } - if let role = node.user?.role, let deviceRole = DeviceRoles(rawValue: Int(role)) { HStack { Label { @@ -189,7 +178,6 @@ struct NodeDetail: View { } .accessibilityElement(children: .combine) } - if let dm = node.telemetries?.filtered(using: NSPredicate(format: "metricsType == 0")).lastObject as? TelemetryEntity, let uptimeSeconds = dm.uptimeSeconds { HStack { Label { @@ -200,7 +188,6 @@ struct NodeDetail: View { .symbolRenderingMode(.hierarchical) } Spacer() - let now = Date.now let later = now + TimeInterval(uptimeSeconds) let uptime = (now.. 0 && firstHeard < Calendar.current.date(byAdding: .year, value: 1, to: Date())! { HStack { Label { @@ -232,7 +218,6 @@ struct NodeDetail: View { dateFormatRelative.toggle() } } - if let lastHeard = node.lastHeard, lastHeard.timeIntervalSince1970 > 0 && lastHeard < Calendar.current.date(byAdding: .year, value: 1, to: Date())! { HStack { Label { @@ -242,7 +227,6 @@ struct NodeDetail: View { .symbolRenderingMode(.multicolor) } Spacer() - if dateFormatRelative, let text = Self.relativeFormatter.string(for: lastHeard) { if lastHeard.formatted() != "Unknown Age".localized { Text(text) @@ -259,7 +243,6 @@ struct NodeDetail: View { } } } - // Note, as you add widgets, you should add to the `hasDataForLatestPositions` array // This will make sure the "Environment" section is only displayed when the node has a position // to use with WeatherKit, or has actual data in the most recent EnvironmentMetrics entity @@ -298,7 +281,7 @@ struct NodeDetail: View { let windGust = node.latestEnvironmentMetrics?.windGust.map { Measurement(value: Double($0), unit: UnitSpeed.metersPerSecond) } let direction = cardinalValue(from: Double(node.latestEnvironmentMetrics?.windDirection ?? 0)) WindCompactWidget(speed: windSpeedMeasurement.formatted(.measurement(width: .abbreviated, numberFormatStyle: .number.precision(.fractionLength(0)))), - gust: node.latestEnvironmentMetrics?.windGust ?? 0.0 > 0.0 ? windGust?.formatted(.measurement(width: .abbreviated, numberFormatStyle: .number.precision(.fractionLength(0)))) : "", direction: direction) + gust: node.latestEnvironmentMetrics?.windGust ?? 0.0 > 0.0 ? windGust?.formatted(.measurement(width: .abbreviated, numberFormatStyle: .number.precision(.fractionLength(0)))) : "", direction: direction) } if let rainfall1h = node.latestEnvironmentMetrics?.rainfall1H { let locale = NSLocale.current as NSLocale @@ -370,7 +353,6 @@ struct NodeDetail: View { } } .disabled(!node.hasDeviceMetrics) - NavigationLink { NodeMapSwiftUI(node: node, showUserLocation: connectedNode?.num ?? 0 == node.num) } label: { @@ -382,7 +364,6 @@ struct NodeDetail: View { } } .disabled(!node.hasPositions) - NavigationLink { PositionLog(node: node) } label: { @@ -394,7 +375,6 @@ struct NodeDetail: View { } } .disabled(!node.hasPositions) - NavigationLink { EnvironmentMetricsLog(node: node) } label: { @@ -406,7 +386,6 @@ struct NodeDetail: View { } } .disabled(!node.hasEnvironmentMetrics) - NavigationLink { TraceRouteLog(node: node) } label: { @@ -418,7 +397,6 @@ struct NodeDetail: View { } } .disabled(node.traceRoutes?.count ?? 0 == 0) - NavigationLink { PowerMetricsLog(node: node) } label: { @@ -430,7 +408,6 @@ struct NodeDetail: View { } } .disabled(!node.hasPowerMetrics) - NavigationLink { DetectionSensorLog(node: node) } label: { @@ -442,7 +419,6 @@ struct NodeDetail: View { } } .disabled(!node.hasDetectionSensorMetrics) - if node.hasPax { NavigationLink { PaxCounterLog(node: node) @@ -457,7 +433,6 @@ struct NodeDetail: View { .disabled(!node.hasPax) } } - Section("Actions") { if let user = node.user { NodeAlertsButton( @@ -466,7 +441,6 @@ struct NodeDetail: View { user: user ) } - if let connectedNode { FavoriteNodeButton( bleManager: bleManager, @@ -491,7 +465,7 @@ struct NodeDetail: View { } if node.hasPositions { NavigateToButton(node: node) - } + } IgnoreNodeButton( bleManager: bleManager, context: context, @@ -506,7 +480,6 @@ struct NodeDetail: View { } } } - if let metadata = node.metadata, let connectedNode, self.bleManager.connectedPeripheral != nil { @@ -529,7 +502,6 @@ struct NodeDetail: View { } } } - if metadata.canShutdown { Button { showingShutdownConfirm = true @@ -549,7 +521,6 @@ struct NodeDetail: View { } } } - Button { showingRebootConfirm = true } label: { diff --git a/Meshtastic/Views/Settings/Channels.swift b/Meshtastic/Views/Settings/Channels.swift index 8e38f27b..b1a2518c 100644 --- a/Meshtastic/Views/Settings/Channels.swift +++ b/Meshtastic/Views/Settings/Channels.swift @@ -241,7 +241,6 @@ struct Channels: View { #endif } } - if node?.myInfo?.channels?.array.count ?? 0 < 8 && node != nil { Button { diff --git a/Meshtastic/Views/Settings/SaveChannelQRCode.swift b/Meshtastic/Views/Settings/SaveChannelQRCode.swift index 49c78b0c..0a83c900 100644 --- a/Meshtastic/Views/Settings/SaveChannelQRCode.swift +++ b/Meshtastic/Views/Settings/SaveChannelQRCode.swift @@ -12,18 +12,14 @@ import MeshtasticProtobufs struct SaveChannelQRCode: View { @Environment(\.dismiss) private var dismiss @Environment(\.managedObjectContext) var context - let channelSetLink: String var addChannels: Bool = false var bleManager: BLEManager - @State private var showError: Bool = false @State private var errorMessage: String = "" @State private var connectedToDevice: Bool = false @State private var loraChanges: [String] = [] @State private var okToMQTT: Bool = false - - var body: some View { VStack { Text("\(addChannels ? "Add" : "Replace all") Channels?") @@ -47,7 +43,6 @@ struct SaveChannelQRCode: View { } .padding() } - if showError { Text(errorMessage.isEmpty ? "Channels being added from the QR code did not save. When adding channels the names must be unique." : errorMessage) .fixedSize(horizontal: false, vertical: true) @@ -55,7 +50,6 @@ struct SaveChannelQRCode: View { .font(.callout) .padding() } - HStack { if !showError { Button { @@ -72,7 +66,6 @@ struct SaveChannelQRCode: View { } else { channelData = channelSetLink } - let success = bleManager.saveChannelSet(base64UrlString: channelData, addChannels: addChannels, okToMQTT: okToMQTT) if success { dismiss() @@ -119,11 +112,8 @@ struct SaveChannelQRCode: View { fetchLoRaConfigChanges() } } - private func extractChannelDataFromURL(_ urlString: String) -> String? { Logger.data.info("Extracting channel data from URL: \(urlString)") - - if let url = URL(string: urlString) { // Get the fragment (part after #) if let fragment = url.fragment, !fragment.isEmpty { @@ -131,7 +121,6 @@ struct SaveChannelQRCode: View { return fragment } } - // Fallback: manually extract everything after the last # if let hashIndex = urlString.lastIndex(of: "#") { let startIndex = urlString.index(after: hashIndex) @@ -141,11 +130,9 @@ struct SaveChannelQRCode: View { return channelData } } - Logger.data.error("Failed to extract channel data from URL: \(urlString)") return nil } - private func fetchLoRaConfigChanges() { var currentLoRaConfig: Config.LoRaConfig? @@ -163,13 +150,10 @@ struct SaveChannelQRCode: View { // Assume it's already the base64 data channelData = channelSetLink } - Logger.data.info("Processing channel data: \(channelData)") - // Fetch current LoRa config from Core Data let fetchRequest = NodeInfoEntity.fetchRequest() fetchRequest.predicate = NSPredicate(format: "num == %lld", Int64(bleManager.connectedPeripheral?.num ?? 0)) - do { let nodes = try context.fetch(fetchRequest) if let node = nodes.first { @@ -178,7 +162,6 @@ struct SaveChannelQRCode: View { } catch { Logger.data.error("Failed to fetch NodeInfoEntity: \(error.localizedDescription, privacy: .public)") } - // Decode base64url string let decodedString = channelData.base64urlToBase64() guard let decodedData = Data(base64Encoded: decodedString) else { @@ -187,7 +170,6 @@ struct SaveChannelQRCode: View { showError = true return } - do { let channelSet = try ChannelSet(serializedBytes: decodedData) let newLoRaConfig = channelSet.loraConfig @@ -244,7 +226,6 @@ struct SaveChannelQRCode: View { } else { // Compare against default values when no current config exists let defaultConfig = getDefaultLoRaConfig() - if newLoRaConfig.hopLimit != defaultConfig.hopLimit { changes.append("Hop Limit: \(defaultConfig.hopLimit) -> \(newLoRaConfig.hopLimit)") } @@ -287,16 +268,13 @@ struct SaveChannelQRCode: View { changes.append("Ignore MQTT: \(defaultConfig.ignoreMqtt) -> \(newLoRaConfig.ignoreMqtt)") } } - loraChanges = changes - } catch { Logger.data.error("Failed to decode ChannelSet: \(error.localizedDescription, privacy: .public)") errorMessage = "Failed to decode channel configuration" showError = true } } - private func getDefaultLoRaConfig() -> Config.LoRaConfig { var config = Config.LoRaConfig() config.hopLimit = 3 @@ -316,7 +294,6 @@ struct SaveChannelQRCode: View { return config } } - extension LoRaConfigEntity { func toProto() -> Config.LoRaConfig { var config = Config.LoRaConfig()