diff --git a/Localizable.xcstrings b/Localizable.xcstrings index a61ea1cf..f17521af 100644 --- a/Localizable.xcstrings +++ b/Localizable.xcstrings @@ -19163,6 +19163,9 @@ }, "Send a message to a certain meshtastic channel" : { + }, + "Send a position on the primary channel when the user button is triple clicked." : { + }, "Send a shutdown to the node you are connected to" : { @@ -21906,6 +21909,9 @@ }, "Treat double tap on supported accelerometers as a user button press." : { + }, + "Triple Click Ad Hoc Ping" : { + }, "Try Again" : { diff --git a/Meshtastic.xcodeproj/project.pbxproj b/Meshtastic.xcodeproj/project.pbxproj index 7d9209f1..2c215a85 100644 --- a/Meshtastic.xcodeproj/project.pbxproj +++ b/Meshtastic.xcodeproj/project.pbxproj @@ -1153,7 +1153,7 @@ attributes = { BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1540; - LastUpgradeCheck = 1540; + LastUpgradeCheck = 1600; TargetAttributes = { 25F5D5C62C4375A8008036E3 = { CreatedOnToolsVersion = 15.4; @@ -1667,7 +1667,6 @@ DDC2E17F26CE248F0042C5E4 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; @@ -1682,7 +1681,7 @@ INFOPLIST_FILE = Meshtastic/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Meshtastic; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; - IPHONEOS_DEPLOYMENT_TARGET = 16.6; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1702,7 +1701,6 @@ DDC2E18026CE248F0042C5E4 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; @@ -1717,7 +1715,7 @@ INFOPLIST_FILE = Meshtastic/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Meshtastic; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; - IPHONEOS_DEPLOYMENT_TARGET = 16.6; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme b/Meshtastic.xcodeproj/xcshareddata/xcschemes/Meshtastic.xcscheme index 9ef67c6d..19c6089f 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){ + if !BLEManager.shared.isConnected { throw AppIntentErrors.AppIntentError.notConnected } - + // Check if channel number is between 1 and 7 guard (0...7).contains(channelNumber) else { throw $channelNumber.needsValueError("Channel number must be between 0 and 7.") } - + // Convert messageContent to data and check its length guard let messageData = messageContent.data(using: .utf8) else { throw AppIntentErrors.AppIntentError.message("Failed to encode message content") } - + if messageData.count > 228 { throw $messageContent.needsValueError("Message content exceeds 228 bytes.") } - if(!BLEManager.shared.sendMessage(message: messageContent, toUserNum: 0, channel: Int32(channelNumber), isEmoji: false, replyID: 0)){ + if !BLEManager.shared.sendMessage(message: messageContent, toUserNum: 0, channel: Int32(channelNumber), isEmoji: false, replyID: 0) { throw AppIntentErrors.AppIntentError.message("Failed to send message") } - - return .result() + + return .result() } } diff --git a/Meshtastic/AppIntents/SendWaypointIntent.swift b/Meshtastic/AppIntents/SendWaypointIntent.swift index 392d232a..4352c548 100644 --- a/Meshtastic/AppIntents/SendWaypointIntent.swift +++ b/Meshtastic/AppIntents/SendWaypointIntent.swift @@ -16,10 +16,10 @@ struct SendWaypointIntent: AppIntent { @Parameter(title: "Name", default: "Dropped Pin") var nameParameter: String? - + @Parameter(title: "Description", default: "") var descriptionParameter: String? - + @Parameter(title: "Emoji", default: "📍") var emojiParameter: String? @@ -27,19 +27,19 @@ struct SendWaypointIntent: AppIntent { var locationParameter: CLPlacemark func perform() async throws -> some IntentResult { - if (!BLEManager.shared.isConnected){ + if !BLEManager.shared.isConnected { throw AppIntentErrors.AppIntentError.notConnected } // Provide default values if parameters are nil let name = nameParameter ?? "Dropped Pin" let description = descriptionParameter ?? "" let emoji = emojiParameter ?? "📍" - + // Validate name length if name.utf8.count > 30 { throw $nameParameter.needsValueError("Name must be less than 30 bytes") } - + // Validate description length if description.utf8.count > 100 { throw $descriptionParameter.needsValueError("Description must be less than 100 bytes") @@ -60,7 +60,6 @@ struct SendWaypointIntent: AppIntent { newWaypoint.longitudeI = Int32(longitude * 10_000_000) } - newWaypoint.id = UInt32.random(in: UInt32(UInt8.max).. } -@available(iOS 17.0, macOS 14.0, *) struct PositionAltitudeChart: View { @Environment(\.dismiss) private var dismiss @ObservedObject var node: NodeInfoEntity diff --git a/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift b/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift index 3f0a528b..35406707 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift @@ -8,7 +8,6 @@ import SwiftUI import MapKit -@available(iOS 17.0, macOS 14.0, *) struct PositionPopover: View { @ObservedObject var locationsHandler = LocationsHandler.shared diff --git a/Meshtastic/Views/Nodes/MeshMap.swift b/Meshtastic/Views/Nodes/MeshMap.swift index 595abb15..da9001ea 100644 --- a/Meshtastic/Views/Nodes/MeshMap.swift +++ b/Meshtastic/Views/Nodes/MeshMap.swift @@ -10,11 +10,8 @@ import CoreData import CoreLocation import Foundation import OSLog -#if canImport(MapKit) import MapKit -#endif -@available(iOS 17.0, macOS 14.0, *) struct MeshMap: View { @Environment(\.managedObjectContext) var context diff --git a/Meshtastic/Views/Nodes/TraceRouteLog.swift b/Meshtastic/Views/Nodes/TraceRouteLog.swift index 345a4299..8166b15f 100644 --- a/Meshtastic/Views/Nodes/TraceRouteLog.swift +++ b/Meshtastic/Views/Nodes/TraceRouteLog.swift @@ -6,11 +6,9 @@ // import SwiftUI -#if canImport(MapKit) import MapKit -#endif -@available(iOS 17.0, macOS 14.0, *) + struct TraceRouteLog: View { @ObservedObject var locationsHandler = LocationsHandler.shared @Environment(\.managedObjectContext) var context diff --git a/Meshtastic/Views/Settings/AppLog.swift b/Meshtastic/Views/Settings/AppLog.swift index fd3db810..e1b2e15c 100644 --- a/Meshtastic/Views/Settings/AppLog.swift +++ b/Meshtastic/Views/Settings/AppLog.swift @@ -8,8 +8,6 @@ import SwiftUI import OSLog -/// Needed for TableColumnForEach -@available(iOS 17.0, macOS 14.0, *) struct AppLog: View { @State private var logs: [OSLogEntryLog] = [] @@ -216,7 +214,6 @@ struct AppLog: View { } } -@available(iOS 17.0, macOS 14.0, *) extension AppLog { @MainActor private func searchAppLogs() async -> [OSLogEntryLog] { diff --git a/Meshtastic/Views/Settings/Channels.swift b/Meshtastic/Views/Settings/Channels.swift index ca55b95d..fbc9f75b 100644 --- a/Meshtastic/Views/Settings/Channels.swift +++ b/Meshtastic/Views/Settings/Channels.swift @@ -10,9 +10,7 @@ import MapKit import MeshtasticProtobufs import OSLog import SwiftUI -#if canImport(TipKit) import TipKit -#endif func generateChannelKey(size: Int) -> String { var keyData = Data(count: size) diff --git a/Meshtastic/Views/Settings/Channels/ChannelForm.swift b/Meshtastic/Views/Settings/Channels/ChannelForm.swift index e4930b7a..b4943db7 100644 --- a/Meshtastic/Views/Settings/Channels/ChannelForm.swift +++ b/Meshtastic/Views/Settings/Channels/ChannelForm.swift @@ -6,9 +6,7 @@ // import SwiftUI -#if canImport(MapKit) import MapKit -#endif struct ChannelForm: View { diff --git a/Meshtastic/Views/Settings/Config/DeviceConfig.swift b/Meshtastic/Views/Settings/Config/DeviceConfig.swift index c78cb845..55359045 100644 --- a/Meshtastic/Views/Settings/Config/DeviceConfig.swift +++ b/Meshtastic/Views/Settings/Config/DeviceConfig.swift @@ -28,6 +28,7 @@ struct DeviceConfig: View { @State var nodeInfoBroadcastSecs = 10800 @State var doubleTapAsButtonPress = false @State var ledHeartbeatEnabled = true + @State var tripleClickAsAdHocPing = true @State var tzdef = "" var body: some View { @@ -76,6 +77,12 @@ struct DeviceConfig: View { Text("Treat double tap on supported accelerometers as a user button press.") } .toggleStyle(SwitchToggleStyle(tint: .accentColor)) + + Toggle(isOn: $tripleClickAsAdHocPing) { + Label("Triple Click Ad Hoc Ping", systemImage: "map.pin") + Text("Send a position on the primary channel when the user button is triple clicked.") + } + .toggleStyle(SwitchToggleStyle(tint: .accentColor)) Toggle(isOn: $ledHeartbeatEnabled) { Label("LED Heartbeat", systemImage: "waveform.path.ecg") @@ -93,13 +100,13 @@ struct DeviceConfig: View { Label("Time Zone", systemImage: "clock.badge.exclamationmark") TextField("Time Zone", text: $tzdef, axis: .vertical) .foregroundColor(.gray) - .onChange(of: tzdef, perform: { _ in + .onChange(of: tzdef) { let totalBytes = tzdef.utf8.count // Only mess with the value if it is too big if totalBytes > 63 { tzdef = String(tzdef.dropLast()) } - }) + } .foregroundColor(.gray) } @@ -268,6 +275,9 @@ struct DeviceConfig: View { .onChange(of: doubleTapAsButtonPress) { if $0 != node?.deviceConfig?.doubleTapAsButtonPress { hasChanges = true } } + .onChange(of: tripleClickAsAdHocPing) { + // if $0 != node?.deviceConfig?.tripleClickAsAdHocPing { hasChanges = true } + } .onChange(of: tzdef) { newTzdef in if newTzdef != node?.deviceConfig?.tzdef { hasChanges = true } } diff --git a/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift b/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift index fe3faa51..5e82da1b 100644 --- a/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/AmbientLightingConfig.swift @@ -8,7 +8,6 @@ import MeshtasticProtobufs import SwiftUI import OSLog -@available(iOS 17.0, macOS 14.0, *) struct AmbientLightingConfig: View { @Environment(\.self) var environment @Environment(\.managedObjectContext) var context diff --git a/Meshtastic/Views/Settings/GPSStatus.swift b/Meshtastic/Views/Settings/GPSStatus.swift index b1119694..c92a647c 100644 --- a/Meshtastic/Views/Settings/GPSStatus.swift +++ b/Meshtastic/Views/Settings/GPSStatus.swift @@ -8,7 +8,6 @@ import SwiftUI import CoreLocation -@available(iOS 17.0, macOS 14.0, *) struct GPSStatus: View { var largeFont: Font = .footnote diff --git a/Meshtastic/Views/Settings/RouteRecorder.swift b/Meshtastic/Views/Settings/RouteRecorder.swift index c19dbd9f..ea2cdc41 100644 --- a/Meshtastic/Views/Settings/RouteRecorder.swift +++ b/Meshtastic/Views/Settings/RouteRecorder.swift @@ -12,7 +12,6 @@ import CoreLocation import CoreMotion import OSLog -@available(iOS 17.0, macOS 14.0, *) struct RouteRecorder: View { @ObservedObject var locationsHandler: LocationsHandler = LocationsHandler.shared diff --git a/Meshtastic/Views/Settings/Routes.swift b/Meshtastic/Views/Settings/Routes.swift index 65be4fd3..c5bcb69c 100644 --- a/Meshtastic/Views/Settings/Routes.swift +++ b/Meshtastic/Views/Settings/Routes.swift @@ -10,7 +10,6 @@ import CoreData import MapKit import OSLog -@available(iOS 17.0, macOS 14.0, *) struct Routes: View { @State private var columnVisibility = NavigationSplitViewVisibility.doubleColumn diff --git a/Meshtastic/Views/Settings/Settings.swift b/Meshtastic/Views/Settings/Settings.swift index 481fb29d..6176512f 100644 --- a/Meshtastic/Views/Settings/Settings.swift +++ b/Meshtastic/Views/Settings/Settings.swift @@ -7,9 +7,7 @@ import SwiftUI import OSLog -#if canImport(TipKit) import TipKit -#endif struct Settings: View { @Environment(\.managedObjectContext) var context diff --git a/Meshtastic/Views/Settings/ShareChannels.swift b/Meshtastic/Views/Settings/ShareChannels.swift index 136b9563..f4f4167a 100644 --- a/Meshtastic/Views/Settings/ShareChannels.swift +++ b/Meshtastic/Views/Settings/ShareChannels.swift @@ -8,10 +8,7 @@ import SwiftUI import CoreData import CoreImage.CIFilterBuiltins import MeshtasticProtobufs - -#if canImport(TipKit) import TipKit -#endif struct QrCodeImage { let context = CIContext()