Merge branch 'main' into BetterReplies

This commit is contained in:
Benjamin Faershtein 2025-05-03 23:45:52 -07:00 committed by GitHub
commit 3bac49ef1f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
117 changed files with 2914 additions and 3270 deletions

File diff suppressed because it is too large Load diff

View file

@ -56,7 +56,6 @@
B399E8A42B6F486400E4488E /* RetryButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B399E8A32B6F486400E4488E /* RetryButton.swift */; };
B3E905B12B71F7F300654D07 /* TextMessageField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3E905B02B71F7F300654D07 /* TextMessageField.swift */; };
BC47C2EF2CE0017D008245CA /* MessageNodeIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC47C2EE2CE0017D008245CA /* MessageNodeIntent.swift */; };
BC5EBA3C2D002A2000C442FF /* MessageNodeIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC5EBA3B2D002A2000C442FF /* MessageNodeIntent.swift */; };
BC6B45FF2CB2F98900723CEB /* SaveChannelSettingsIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC6B45FE2CB2F98900723CEB /* SaveChannelSettingsIntent.swift */; };
BCB613812C67290800485544 /* SendWaypointIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613802C67290800485544 /* SendWaypointIntent.swift */; };
BCB613832C672A2600485544 /* MessageChannelIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB613822C672A2600485544 /* MessageChannelIntent.swift */; };
@ -146,7 +145,6 @@
DD8EBF43285058FA00426DCA /* DisplayConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8EBF42285058FA00426DCA /* DisplayConfig.swift */; };
DD8ED9C52898D51F00B3B0AB /* NetworkConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8ED9C42898D51F00B3B0AB /* NetworkConfig.swift */; };
DD8ED9C8289CE4B900B3B0AB /* RoutingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8ED9C7289CE4B900B3B0AB /* RoutingError.swift */; };
DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD90860D26F69BAE00DC5189 /* NodeMap.swift */; };
DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD913638270DFF4C00D7ACF3 /* LocalNotificationManager.swift */; };
DD93800B2BA3F968008BEC06 /* NodeMapContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD93800A2BA3F968008BEC06 /* NodeMapContent.swift */; };
DD93800E2BA74D0C008BEC06 /* ChannelForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD93800D2BA74D0C008BEC06 /* ChannelForm.swift */; };
@ -437,7 +435,6 @@
DD8ED9C42898D51F00B3B0AB /* NetworkConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkConfig.swift; sourceTree = "<group>"; };
DD8ED9C7289CE4B900B3B0AB /* RoutingError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoutingError.swift; sourceTree = "<group>"; };
DD90860A26F645B700DC5189 /* Meshtastic.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Meshtastic.entitlements; sourceTree = "<group>"; };
DD90860D26F69BAE00DC5189 /* NodeMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeMap.swift; sourceTree = "<group>"; };
DD913638270DFF4C00D7ACF3 /* LocalNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalNotificationManager.swift; sourceTree = "<group>"; };
DD93800A2BA3F968008BEC06 /* NodeMapContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeMapContent.swift; sourceTree = "<group>"; };
DD93800D2BA74D0C008BEC06 /* ChannelForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelForm.swift; sourceTree = "<group>"; };
@ -731,7 +728,6 @@
DDDB263E2AABEE20003AFCB7 /* NodeList.swift */,
DD769E0228D18BF0001A3F05 /* DeviceMetricsLog.swift */,
DDAD49EC2AFB39DC00B4425D /* MeshMap.swift */,
DD90860D26F69BAE00DC5189 /* NodeMap.swift */,
DD73FD1028750779000852D6 /* PositionLog.swift */,
DD4F23CC28779A3C001D37CB /* EnvironmentMetricsLog.swift */,
6DEDA5592A957B8E00321D2E /* DetectionSensorLog.swift */,
@ -1240,7 +1236,7 @@
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 1540;
LastUpgradeCheck = 1600;
LastUpgradeCheck = 1630;
TargetAttributes = {
25F5D5C62C4375A8008036E3 = {
CreatedOnToolsVersion = 15.4;
@ -1404,7 +1400,6 @@
DDC4D568275499A500A4208E /* Persistence.swift in Sources */,
DDD6EEAF29BC024700383354 /* Firmware.swift in Sources */,
DD77093B2AA1ABB8007A8BF0 /* BluetoothTips.swift in Sources */,
DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */,
D9C9839D2B79CFD700BDBE6A /* TextMessageSize.swift in Sources */,
DDC94FCE29CF55310082EA6E /* RtttlConfig.swift in Sources */,
DD964FBD296E6B01007C176F /* EmojiOnlyTextField.swift in Sources */,
@ -1486,7 +1481,6 @@
251926872C3BAE2200249DF5 /* NodeAlertsButton.swift in Sources */,
DDA1C48E28DB49D3009933EC /* ChannelRoles.swift in Sources */,
DDD5BB092C285DDC007E03CA /* AppLog.swift in Sources */,
BC5EBA3C2D002A2000C442FF /* MessageNodeIntent.swift in Sources */,
DD8ED9C8289CE4B900B3B0AB /* RoutingError.swift in Sources */,
233E99C52D84A0B600CC3A77 /* CompactWidget.swift in Sources */,
DDC1B81A2AB5377B00C71E39 /* MessagesTips.swift in Sources */,
@ -1608,7 +1602,6 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = GCH7VS5Y9R;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
@ -1632,7 +1625,6 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = GCH7VS5Y9R;
GCC_C_LANGUAGE_STANDARD = gnu17;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
@ -1682,6 +1674,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = GCH7VS5Y9R;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
@ -1746,6 +1739,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = GCH7VS5Y9R;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
@ -1782,7 +1776,6 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"Meshtastic/Preview Content\"";
DEVELOPMENT_TEAM = GCH7VS5Y9R;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Meshtastic/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Meshtastic;
@ -1792,7 +1785,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.5.23;
MARKETING_VERSION = 2.6.0;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
@ -1816,7 +1809,6 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"Meshtastic/Preview Content\"";
DEVELOPMENT_TEAM = GCH7VS5Y9R;
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Meshtastic/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Meshtastic;
@ -1826,7 +1818,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.5.23;
MARKETING_VERSION = 2.6.0;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
@ -1847,7 +1839,6 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = GCH7VS5Y9R;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Widgets/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Widgets;
@ -1858,7 +1849,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.5.23;
MARKETING_VERSION = 2.6.0;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1880,7 +1871,6 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = GCH7VS5Y9R;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Widgets/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Widgets;
@ -1891,7 +1881,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.5.23;
MARKETING_VERSION = 2.6.0;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1600"
LastUpgradeVersion = "1630"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1600"
LastUpgradeVersion = "1630"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"

View file

@ -16,7 +16,7 @@ class AppIntentErrors {
var localizedStringResource: LocalizedStringResource {
switch self {
case let .message(message):
Logger.services.error("App Intent: \(message,privacy: .public)")
Logger.services.error("App Intent: \(message, privacy: .public)")
return "Error: \(message)"
case .notConnected:
Logger.services.error("App Intent: No Connected Node")

View file

@ -13,38 +13,38 @@ import UIKit
@available(iOS 16.4, *)
struct NavigateToNodeIntent: ForegroundContinuableIntent {
static var title: LocalizedStringResource = "Navigate to Node Position"
static var openAppWhenRun: Bool = false
@Parameter(title: "Node Number")
var nodeNum: Int
@MainActor
func perform() async throws -> some IntentResult & ProvidesDialog {
if !BLEManager.shared.isConnected {
throw AppIntentErrors.AppIntentError.notConnected
}
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "NodeInfoEntity")
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
do {
guard let fetchedNode = try PersistenceController.shared.container.viewContext.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity],
fetchedNode.count == 1 else {
throw $nodeNum.needsValueError("Could not find node")
}
let nodeInfo = fetchedNode[0]
if let latitude = nodeInfo.latestPosition?.coordinate.latitude,
let longitude = nodeInfo.latestPosition?.coordinate.longitude {
let url = URL(string: "maps://?saddr=&daddr=\(latitude),\(longitude)")
if let mapURL = url, UIApplication.shared.canOpenURL(mapURL) {
// Request to continue in foreground before opening the app
try await requestToContinueInForeground()
// Open Apple Maps for navigation
UIApplication.shared.open(mapURL, options: [:], completionHandler: nil)
return .result(dialog: "Navigating to node location.")

View file

@ -29,12 +29,9 @@ struct SaveChannelSettingsIntent: AppIntent {
if channelUrl.absoluteString.lowercased().contains("meshtastic.org/e/#") {
// Split the URL to get the portion after "#"
let components = channelUrl.absoluteString.components(separatedBy: "#")
// Add channels flag based on the URL query parameter (if present)
let addChannels = Bool(channelUrl["add"] ?? "false") ?? false
var channelSettings: String?
// Extract the Base64 encoded channel settings (after "#")
if let lastComponent = components.last {
channelSettings = lastComponent.components(separatedBy: "?").first // Ignore any query parameters
@ -44,7 +41,6 @@ struct SaveChannelSettingsIntent: AppIntent {
if let channelSettings = channelSettings {
// Call the BLEManager to save the channel settings
let saveResult = BLEManager.shared.saveChannelSet(base64UrlString: channelSettings, addChannels: addChannels)
if !saveResult {
throw AppIntentErrors.AppIntentError.message("Failed to save the channel settings.")
}

View file

@ -19,7 +19,7 @@ enum MeshMapTypes: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .standard:
return "standard".localized
return "Standard".localized
case .mutedStandard:
return "standard.muted".localized
case .hybrid:

View file

@ -19,11 +19,11 @@ enum ConfigPresets: Int, CaseIterable, Identifiable {
switch self {
case .unset:
return "canned.messages.preset.manual".localized
return "Manual Configuration".localized
case .rakRotaryEncoder:
return "canned.messages.preset.rakrotary".localized
return "RAK Rotary Encoder".localized
case .cardKB:
return "canned.messages.preset.cardkb".localized
return "M5 Stack Card KB / RAK Keypad".localized
}
}
}

View file

@ -19,11 +19,11 @@ enum ChannelRoles: Int, CaseIterable, Identifiable {
switch self {
case .disabled:
return "channel.role.disabled".localized
return "Disabled".localized
case .primary:
return "channel.role.primary".localized
return "Primary".localized
case .secondary:
return "channel.role.secondary".localized
return "Secondary".localized
}
}
func protoEnumValue() -> Channel.Role {

View file

@ -144,7 +144,8 @@ enum RebroadcastModes: Int, CaseIterable, Identifiable {
case allSkipDecoding = 1
case localOnly = 2
case knownOnly = 3
case corePortnums = 4
case none = 4
case corePortnums = 5
var id: Int { self.rawValue }
@ -158,6 +159,8 @@ enum RebroadcastModes: Int, CaseIterable, Identifiable {
return "Local Only"
case .knownOnly:
return "Known Only"
case .none:
return "None"
case .corePortnums:
return "Core Portnums Only"
}
@ -172,6 +175,8 @@ enum RebroadcastModes: Int, CaseIterable, Identifiable {
return "Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. Only rebroadcasts message on the nodes local primary / secondary channels."
case .knownOnly:
return "Ignores observed messages from foreign meshes like Local Only, but takes it step further by also ignoring messages from nodes not already in the node's known list."
case .none:
return "Only permitted for SENSOR, TRACKER and TAK_TRACKER roles, this will inhibit all rebroadcasts, not unlike CLIENT_MUTE role."
case .corePortnums:
return "Only rebroadcasts packets from the core portnums: NodeInfo, Text, Position, Telemetry, and Routing."
}
@ -187,6 +192,8 @@ enum RebroadcastModes: Int, CaseIterable, Identifiable {
return Config.DeviceConfig.RebroadcastMode.localOnly
case .knownOnly:
return Config.DeviceConfig.RebroadcastMode.knownOnly
case .none:
return Config.DeviceConfig.RebroadcastMode.none
case .corePortnums:
return Config.DeviceConfig.RebroadcastMode.corePortnumsOnly
}

View file

@ -22,7 +22,7 @@ enum NagIntervals: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .unset:
return "unset".localized
return "Unset".localized
case .oneSecond:
return "interval.one.second".localized
case .fiveSeconds:
@ -59,7 +59,7 @@ enum OutputIntervals: Int, CaseIterable, Identifiable {
switch self {
case .unset:
return "unset".localized
return "Unset".localized
case .oneSecond:
return "interval.one.second".localized
case .twoSeconds:

View file

@ -291,9 +291,9 @@ enum ModemPresets: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .longFast:
return "long.range.fast".localized
return "Long Range - Fast".localized
case .longSlow:
return "long.range.slow".localized
return "Long Range - Slow".localized
case .longModerate:
return "long.range.moderate".localized
case .vLongSlow:

View file

@ -110,11 +110,11 @@ enum GpsMode: Int, CaseIterable, Equatable {
var description: String {
switch self {
case .disabled:
return "gpsmode.disabled".localized
return "Disabled".localized
case .enabled:
return "gpsmode.enabled".localized
return "Enabled".localized
case .notPresent:
return "gpsmode.notPresent".localized
return "Not Present".localized
}
}
func protoEnumValue() -> Config.PositionConfig.GpsMode {

View file

@ -31,7 +31,7 @@ enum SerialBaudRates: Int, CaseIterable, Identifiable {
switch self {
case .baudDefault:
return "default".localized
return "Default".localized
case .baud110:
return "110 Baud"
case .baud300:
@ -118,7 +118,7 @@ enum SerialModeTypes: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .default:
return "serial.mode.default".localized
return "Default".localized
case .simple:
return "serial.mode.simple".localized
case .proto:
@ -166,7 +166,7 @@ enum SerialTimeoutIntervals: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .unset:
return "unset".localized
return "Unset".localized
case .oneSecond:
return "interval.one.second".localized
case .fiveSeconds:

View file

@ -20,13 +20,10 @@ struct CsvDocument: FileDocument {
}
init(configuration: ReadConfiguration) throws {
if let data = configuration.file.regularFileContents {
csvData = String(decoding: data, as: UTF8.self)
csvData = String(data: data, encoding: .utf8) ?? ""
} else {
throw CocoaError(.fileReadCorruptFile)
}
}

View file

@ -14,7 +14,7 @@ func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin
let dateFormatString = (localeDateFormat ?? "MM/dd/YY j:mma").replacingOccurrences(of: ",", with: "")
if metricsType == 0 {
// Create Device Metrics Header
csvString = "\("battery.level".localized), \("Voltage".localized), \("channel.utilization".localized), \("airtime".localized), \("uptime".localized), \("Timestamp".localized)"
csvString = "\("battery.level".localized), \("Voltage".localized), \("Channel Utilization".localized), \("airtime".localized), \("Uptime".localized), \("Timestamp".localized)"
for dm in telemetry where dm.metricsType == 0 {
csvString += "\n"
csvString += dm.batteryLevel?.formatted(.number.grouping(.never)) ?? ""
@ -27,7 +27,7 @@ func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin
csvString += ", "
csvString += dm.uptimeSeconds?.formatted(.number.grouping(.never)) ?? ""
csvString += ", "
csvString += dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized
csvString += dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized
}
} else if metricsType == 1 {
// Create Environment Telemetry Header
@ -44,7 +44,7 @@ func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin
csvString += ", "
csvString += dm.gasResistance?.formatted(.number.grouping(.never)) ?? ""
csvString += ", "
csvString += dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized
csvString += dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized
}
} else if metricsType == 2 {
// Create Power Metrics Header
@ -63,7 +63,7 @@ func telemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin
csvString += ", "
csvString += dm.powerCh3Current?.formatted(.number.grouping(.never)) ?? ""
csvString += ", "
csvString += dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized
csvString += dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized
}
}
return csvString
@ -121,7 +121,7 @@ func paxToCsvFile(pax: [PaxCounterEntity]) -> String {
csvString += ", "
csvString += String(p.uptime)
csvString += ", "
csvString += p.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized
csvString += p.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized
}
return csvString
}
@ -150,7 +150,7 @@ func positionToCsvFile(positions: [PositionEntity]) -> String {
csvString += ", "
csvString += String(pos.snr)
csvString += ", "
csvString += pos.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized
csvString += pos.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized
}
return csvString
}

View file

@ -89,6 +89,6 @@ extension PositionEntity {
extension PositionEntity: MKAnnotation {
public var coordinate: CLLocationCoordinate2D { nodeCoordinate ?? LocationsHandler.DefaultLocation }
public var title: String? { nodePosition?.user?.shortName ?? "unknown".localized }
public var title: String? { nodePosition?.user?.shortName ?? "Unknown".localized }
public var subtitle: String? { time?.formatted() }
}

View file

@ -13,7 +13,7 @@ extension Date {
if self.timeIntervalSince1970 > 0 && self < Calendar.current.date(byAdding: .year, value: 1, to: Date())! {
formatted()
} else {
"unknown.age".localized
"Unknown Age".localized
}
}
@ -23,7 +23,7 @@ extension Date {
if self.timeIntervalSince1970 > 0 && self < Calendar.current.date(byAdding: .year, value: 1, to: Date())! {
return dateformat.string(from: self)
} else {
return "unknown.age".localized
return "Unknown Age".localized
}
}
func relativeTimeOfDay() -> String {

View file

@ -18,7 +18,7 @@ extension OSLogEntryLog.Level {
case .notice: "⚠️ Notice"
case .error: "🚨 Error"
case .fault: "💥 Fault"
@unknown default: "default"
@unknown default: "Default".localized
}
}
var color: Color {

View file

@ -72,6 +72,7 @@ extension UserDefaults {
case firmwareVersion
case environmentEnableWeatherKit
case enableAdministration
case mapReportingOptIn
case testIntEnum
}
@ -148,6 +149,9 @@ extension UserDefaults {
@UserDefault(.enableAdministration, defaultValue: false)
static var enableAdministration: Bool
@UserDefault(.mapReportingOptIn, defaultValue: false)
static var mapReportingOptIn: Bool
@UserDefault(.testIntEnum, defaultValue: .one)
static var testIntEnum: TestIntEnum
}

View file

@ -231,7 +231,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
cancelPeripheralConnection()
if errorCode == 14 { // Peer removed pairing information
// Forgetting and reconnecting seems to be necessary so we need to show the user an error telling them to do that
lastConnectionError = "🚨 " + String.localizedStringWithFormat("%@ This error usually cannot be fixed without forgetting the device unders Settings > Bluetooth and re pairing the radio.".localized, e.localizedDescription)
lastConnectionError = "🚨 " + String.localizedStringWithFormat("%@ This error usually cannot be fixed without forgetting the device under Settings > Bluetooth and re pairing the radio.".localized, e.localizedDescription)
Logger.services.error("🚨 [BLE] Failed to connect: \(peripheral.name ?? "Unknown".localized) Error Code: \(errorCode, privacy: .public) Error: \(self.lastConnectionError, privacy: .public)")
} else {
lastConnectionError = "🚨 \(e.localizedDescription)"
@ -261,7 +261,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
Notification(
id: (peripheral.identifier.uuidString),
title: "Radio Disconnected".localized,
subtitle: "\(peripheral.name ?? "unknown".localized)",
subtitle: "\(peripheral.name ?? "Unknown".localized)",
content: e.localizedDescription,
target: "bluetooth",
path: "meshtastic:///bluetooth"
@ -273,7 +273,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown".localized, privacy: .public) Error Code: \(errorCode, privacy: .public) Error: \(e.localizedDescription, privacy: .public)")
} else if errorCode == 14 { // Peer removed pairing information
// Forgetting and reconnecting seems to be necessary so we need to show the user an error telling them to do that
lastConnectionError = "🚨 " + String.localizedStringWithFormat("%@ This error usually cannot be fixed without forgetting the device unders Settings > Bluetooth and re-connecting to the radio.".localized, e.localizedDescription)
lastConnectionError = "🚨 " + String.localizedStringWithFormat("%@ This error usually cannot be fixed without forgetting the device under Settings > Bluetooth and re-connecting to the radio.".localized, e.localizedDescription)
Logger.services.error("🚨 [BLE] Disconnected: \(peripheral.name ?? "Unknown".localized) Error Code: \(errorCode, privacy: .public) Error: \(self.lastConnectionError, privacy: .public)")
} else {
if UserDefaults.preferredPeripheralId == peripheral.identifier.uuidString {
@ -281,7 +281,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
Notification(
id: (peripheral.identifier.uuidString),
title: "Radio Disconnected".localized,
subtitle: "\(peripheral.name ?? "unknown".localized)",
subtitle: "\(peripheral.name ?? "Unknown".localized)",
content: e.localizedDescription,
target: "bluetooth",
path: "meshtastic:///bluetooth"
@ -428,7 +428,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
return 0
}
let messageDescription = "🛎️ [Device Metadata] Requested for node \(toUser.longName ?? "unknown".localized) by \(fromUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ [Device Metadata] Requested for node \(toUser.longName ?? "Unknown".localized) by \(fromUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return Int64(meshPacket.id)
}
@ -477,7 +477,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
traceRoute.node = receivingNode
do {
try context.save()
Logger.data.info("💾 Saved TraceRoute sent to node: \(String(receivingNode?.user?.longName ?? "unknown".localized), privacy: .public)")
Logger.data.info("💾 Saved TraceRoute sent to node: \(String(receivingNode?.user?.longName ?? "Unknown".localized), privacy: .public)")
} catch {
context.rollback()
let nsError = error as NSError
@ -503,7 +503,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
return
} else {
let nodeName = connectedPeripheral?.peripheral.name ?? "unknown".localized
let nodeName = connectedPeripheral?.peripheral.name ?? "Unknown".localized
let logString = String.localizedStringWithFormat("mesh.log.wantconfig %@".localized, nodeName)
Logger.mesh.info("🛎️ \(logString, privacy: .public)")
// BLE Characteristics discovered, issue wantConfig
@ -579,7 +579,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if let error {
Logger.services.error("🚫 [BLE] didUpdateValueFor Characteristic error \(error.localizedDescription, privacy: .public)")
let errorCode = (error as NSError).code
if errorCode == 5 || errorCode == 15 {
@ -633,14 +632,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
} catch {
Logger.services.error("💥 \(error.localizedDescription, privacy: .public) \(characteristic.value!, privacy: .public)")
}
// Publish mqttClientProxyMessages received on the from radio
if decodedInfo.payloadVariant == FromRadio.OneOf_PayloadVariant.mqttClientProxyMessage(decodedInfo.mqttClientProxyMessage) {
let message = CocoaMQTTMessage(
topic: decodedInfo.mqttClientProxyMessage.topic,
payload: [UInt8](decodedInfo.mqttClientProxyMessage.data),
retained: decodedInfo.mqttClientProxyMessage.retained
)
let message = CocoaMQTTMessage(topic: decodedInfo.mqttClientProxyMessage.topic, payload: [UInt8](decodedInfo.mqttClientProxyMessage.data), retained: decodedInfo.mqttClientProxyMessage.retained)
mqttManager.mqttClientProxy?.publish(message)
} else if decodedInfo.payloadVariant == FromRadio.OneOf_PayloadVariant.clientNotification(decodedInfo.clientNotification) {
if decodedInfo.clientNotification.hasReplyID {
@ -686,8 +680,8 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
if myInfo != nil {
UserDefaults.preferredPeripheralNum = Int(myInfo?.myNodeNum ?? 0)
connectedPeripheral.num = myInfo?.myNodeNum ?? 0
connectedPeripheral.name = myInfo?.bleName ?? "unknown".localized
connectedPeripheral.longName = myInfo?.bleName ?? "unknown".localized
connectedPeripheral.name = myInfo?.bleName ?? "Unknown".localized
connectedPeripheral.longName = myInfo?.bleName ?? "Unknown".localized
let newConnection = Int64(UserDefaults.preferredPeripheralNum) != Int64(decodedInfo.myInfo.myNodeNum)
if newConnection {
// Onboard a new device connection here
@ -702,7 +696,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
if self.connectedPeripheral != nil && self.connectedPeripheral.num == nodeInfo.num {
if nodeInfo.user != nil {
connectedPeripheral.shortName = nodeInfo.user?.shortName ?? "?"
connectedPeripheral.longName = nodeInfo.user?.longName ?? "unknown".localized
connectedPeripheral.longName = nodeInfo.user?.longName ?? "Unknown".localized
}
}
}
@ -782,13 +776,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
adminAppPacket(packet: decodedInfo.packet, context: context)
case .replyApp:
Logger.mesh.info("🕸️ MESH PACKET received for Reply App handling as a text message")
textMessageAppPacket(
packet: decodedInfo.packet,
wantRangeTestPackets: wantRangeTestPackets,
connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0),
context: context,
appState: appState
)
textMessageAppPacket(packet: decodedInfo.packet, wantRangeTestPackets: wantRangeTestPackets, connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0), context: context, appState: appState)
case .ipTunnelApp:
Logger.mesh.info("🕸️ MESH PACKET received for IP Tunnel App UNHANDLED UNHANDLED")
case .serialApp:
@ -873,13 +861,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
hopNodes.append(traceRouteHop)
let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "unknown".localized))
let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "Unknown".localized))
let mqttLabel = hopNode?.viaMqtt ?? false ? "MQTT " : ""
let snrLabel = (traceRouteHop.snr != -32) ? String(traceRouteHop.snr) : "unknown ".localized
routeString += "\(hopName) \(mqttLabel)(\(snrLabel)dB) --> "
}
let destinationHop = TraceRouteHopEntity(context: context)
destinationHop.name = traceRoute?.node?.user?.longName ?? "unknown".localized
destinationHop.name = traceRoute?.node?.user?.longName ?? "Unknown".localized
destinationHop.time = Date()
// If nil, set to unknown, INT8_MIN (-128) then divide by 4
destinationHop.snr = Float(routingMessage.snrTowards.last ?? -128) / 4
@ -892,14 +880,14 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
hopNodes.append(destinationHop)
/// Add the destination node to the end of the route towards string and the beginning of the route back string
routeString += "\(traceRoute?.node?.user?.longName ?? "unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) (\(destinationHop.snr != -32 ? String(destinationHop.snr) : "unknown ".localized)dB)"
routeString += "\(traceRoute?.node?.user?.longName ?? "Unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) (\(destinationHop.snr != -32 ? String(destinationHop.snr) : "unknown ".localized)dB)"
traceRoute?.routeText = routeString
// Default to -1 only fill in if routeBack is valid below
traceRoute?.hopsBack = -1
// Only if hopStart is set and there is an SNR entry
if decodedInfo.packet.hopStart > 0 && routingMessage.snrBack.count > 0 {
traceRoute?.hopsBack = Int32(routingMessage.routeBack.count)
var routeBackString = "\(traceRoute?.node?.user?.longName ?? "unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) --> "
var routeBackString = "\(traceRoute?.node?.user?.longName ?? "Unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) --> "
for (index, node) in routingMessage.routeBack.enumerated() {
var hopNode = getNodeInfo(id: Int64(node), context: context)
if hopNode == nil && hopNode?.num ?? 0 > 0 && node != 4294967295 {
@ -930,7 +918,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
hopNodes.append(traceRouteHop)
let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "unknown".localized))
let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "Unknown".localized))
let mqttLabel = hopNode?.viaMqtt ?? false ? "MQTT " : ""
let snrLabel = (traceRouteHop.snr != -32) ? String(traceRouteHop.snr) : "unknown ".localized
routeBackString += "\(hopName) \(mqttLabel)(\(snrLabel)dB) --> "
@ -950,7 +938,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
id: (UUID().uuidString),
title: "Traceroute Complete",
subtitle: "TR received back from \(destinationHop.name ?? "unknown")",
content: "Hops from: \(tr.hopsTowards), Hops back: \(tr.hopsBack)\n\(tr.routeText ?? "unknown".localized)\n\(tr.routeBackText ?? "unknown".localized)",
content: "Hops from: \(tr.hopsTowards), Hops back: \(tr.hopsBack)\n\(tr.routeText ?? "Unknown".localized)\n\(tr.routeBackText ?? "Unknown".localized)",
target: "nodes",
path: "meshtastic:///nodes?nodenum=\(connectedNode.user?.num ?? 0)"
)
@ -1069,7 +1057,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
if preferredPeripheral != nil && preferredPeripheral?.peripheral != nil {
connectTo(peripheral: preferredPeripheral!.peripheral)
}
let nodeName = connectedPeripheral?.peripheral.name ?? "unknown".localized
let nodeName = connectedPeripheral?.peripheral.name ?? "Unknown".localized
let logString = String.localizedStringWithFormat("mesh.log.textmessage.send.failed %@".localized, nodeName)
Logger.mesh.info("🚫 \(logString, privacy: .public)")
@ -1304,7 +1292,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
} else {
return false
}
let messageDescription = "🚀 Sent Set Fixed Postion Admin Message to: \(fromUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
let messageDescription = "🚀 Sent Set Fixed Postion Admin Message to: \(fromUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -1329,7 +1317,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
} else {
return false
}
let messageDescription = "🚀 Sent Remove Fixed Position Admin Message to: \(fromUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
let messageDescription = "🚀 Sent Remove Fixed Position Admin Message to: \(fromUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -1434,7 +1422,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
} else {
return false
}
let messageDescription = "🚀 Sent Shutdown Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
let messageDescription = "🚀 Sent Shutdown Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -1462,7 +1450,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
} else {
return false
}
let messageDescription = "🚀 Sent Reboot Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
let messageDescription = "🚀 Sent Reboot Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -1490,7 +1478,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
} else {
return false
}
let messageDescription = "🚀 Sent Reboot OTA Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
let messageDescription = "🚀 Sent Reboot OTA Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -1519,7 +1507,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
return false
}
automaticallyReconnect = false
let messageDescription = "🚀 Sent enter DFU mode Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
let messageDescription = "🚀 Sent enter DFU mode Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -1547,7 +1535,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
return false
}
let messageDescription = "🚀 Sent Factory Reset Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
let messageDescription = "🚀 Sent Factory Reset Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -1574,7 +1562,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🚀 Sent NodeDB Reset Admin Message to: \(toUser.longName ?? "unknown".localized) from: \(fromUser.longName ?? "unknown".localized)"
let messageDescription = "🚀 Sent NodeDB Reset Admin Message to: \(toUser.longName ?? "Unknown".localized) from: \(fromUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -1617,7 +1605,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.wantResponse = true
meshPacket.decoded = dataMessage
let messageDescription = "🎛️ Requested Channel \(channel.index) for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🎛️ Requested Channel \(channel.index) for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return Int64(meshPacket.id)
}
@ -1641,7 +1629,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.wantResponse = true
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Channel \(channel.index) for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Channel \(channel.index) for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return Int64(meshPacket.id)
}
@ -1790,7 +1778,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
} else {
return 0
}
let messageDescription = "🛟 Saved User Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved User Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return Int64(meshPacket.id)
}
@ -1972,7 +1960,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.payload = adminData
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Ham Parameters for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Ham Parameters for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return Int64(meshPacket.id)
}
@ -1998,7 +1986,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.payload = adminData
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Bluetooth Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Bluetooth Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertBluetoothConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context)
@ -2029,7 +2017,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.payload = adminData
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Device Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Device Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertDeviceConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context)
return Int64(meshPacket.id)
@ -2059,7 +2047,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.payload = adminData
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Display Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Display Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertDisplayConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context)
return Int64(meshPacket.id)
@ -2088,7 +2076,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.payload = adminData
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved LoRa Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved LoRa Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertLoRaConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context)
@ -2120,7 +2108,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Position Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Position Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertPositionConfigPacket(config: config, nodeNum: toUser.num, context: context)
@ -2151,7 +2139,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Power Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Power Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertPowerConfigPacket(config: config, nodeNum: toUser.num, context: context)
@ -2184,7 +2172,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Network Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Network Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertNetworkConfigPacket(config: config, nodeNum: toUser.num, context: context)
@ -2217,7 +2205,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Security Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Security Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertSecurityConfigPacket(config: config, nodeNum: toUser.num, context: context)
@ -2249,7 +2237,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Ambient Lighting Module Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Ambient Lighting Module Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertAmbientLightingModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
@ -2281,7 +2269,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Canned Message Module Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Canned Message Module Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertCannedMessagesModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
@ -2314,7 +2302,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.wantResponse = true
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Canned Message Module Messages for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Canned Message Module Messages for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
@ -2347,7 +2335,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Detection Sensor Module Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Detection Sensor Module Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertDetectionSensorModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
@ -2378,7 +2366,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved External Notification Module Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved External Notification Module Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertExternalNotificationModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
@ -2409,7 +2397,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved PAX Counter Module Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved PAX Counter Module Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertPaxCounterModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
@ -2440,7 +2428,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved RTTTL Ringtone Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved RTTTL Ringtone Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertRtttlConfigPacket(ringtone: ringtone, nodeNum: toUser.num, context: context)
@ -2474,7 +2462,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved MQTT Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved MQTT Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertMqttModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
@ -2504,7 +2492,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Range Test Module Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Range Test Module Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertRangeTestModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
@ -2537,7 +2525,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Serial Module Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Serial Module Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertSerialModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
@ -2568,7 +2556,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Store & Forward Module Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛟 Saved Store & Forward Module Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertStoreForwardModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
@ -2599,7 +2587,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.portnum = PortNum.adminApp
meshPacket.decoded = dataMessage
let messageDescription = "Saved Telemetry Module Config for \(toUser.longName ?? "unknown".localized)"
let messageDescription = "Saved Telemetry Module Config for \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertTelemetryModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
@ -2629,7 +2617,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Sent a Get Channel \(channelIndex) Request Admin Message for node: \(toUser.longName ?? "unknown".localized))"
let messageDescription = "🛎️ Sent a Get Channel \(channelIndex) Request Admin Message for node: \(toUser.longName ?? "Unknown".localized))"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
@ -2735,7 +2723,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Device Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Device Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
@ -2765,7 +2753,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Display Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Display Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
@ -2795,7 +2783,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested LoRa Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested LoRa Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
@ -2826,7 +2814,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
dataMessage.wantResponse = true
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Network Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Network Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
@ -2856,7 +2844,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Position Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Position Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -2885,7 +2873,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Power Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Power Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -2914,7 +2902,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Security Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Security Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -2943,7 +2931,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Ambient Lighting Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Ambient Lighting Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -2972,7 +2960,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Canned Messages Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Canned Messages Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -3001,7 +2989,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested External Notificaiton Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested External Notificaiton Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -3030,7 +3018,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested PAX Counter Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested PAX Counter Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -3059,7 +3047,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested RTTTL Ringtone Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested RTTTL Ringtone Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -3088,7 +3076,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Range Test Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Range Test Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -3146,7 +3134,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Detection Sensor Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Detection Sensor Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -3175,7 +3163,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Serial Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Serial Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -3204,7 +3192,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Store and Forward Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Store and Forward Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -3234,7 +3222,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛎️ Requested Telemetry Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "unknown".localized)"
let messageDescription = "🛎️ Requested Telemetry Module Config on admin channel \(adminIndex) for node: \(toUser.longName ?? "Unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
return true
}
@ -3448,7 +3436,7 @@ extension BLEManager: CBCentralManagerDelegate {
case .unsupported:
status = "BLE is unsupported"
default:
status = "default"
status = "Default".localized
}
Logger.services.info("📜 [BLE] Bluetooth status: \(status, privacy: .public)")
}

View file

@ -625,7 +625,7 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana
let routingError = RoutingError(rawValue: routingMessage.errorReason.rawValue)
let routingErrorString = routingError?.display ?? "unknown".localized
let routingErrorString = routingError?.display ?? "Unknown".localized
let logString = String.localizedStringWithFormat("mesh.log.routing.message %@ %@".localized, String(packet.decoded.requestID), routingErrorString)
Logger.mesh.info("🕸️ \(logString, privacy: .public)")
@ -686,20 +686,15 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana
func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManagedObjectContext) {
if let telemetryMessage = try? Telemetry(serializedBytes: packet.decoded.payload) {
let logString = String.localizedStringWithFormat("mesh.log.telemetry.received %@".localized, String(packet.from))
Logger.mesh.info("📈 \(logString, privacy: .public)")
if telemetryMessage.variant != Telemetry.OneOf_Variant.deviceMetrics(telemetryMessage.deviceMetrics) && telemetryMessage.variant != Telemetry.OneOf_Variant.environmentMetrics(telemetryMessage.environmentMetrics) && telemetryMessage.variant != Telemetry.OneOf_Variant.localStats(telemetryMessage.localStats) && telemetryMessage.variant != Telemetry.OneOf_Variant.powerMetrics(telemetryMessage.powerMetrics) {
/// Other unhandled telemetry packets
return
}
let telemetry = TelemetryEntity(context: context)
let fetchNodeTelemetryRequest = NodeInfoEntity.fetchRequest()
fetchNodeTelemetryRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from))
do {
let fetchedNode = try context.fetch(fetchNodeTelemetryRequest)
if fetchedNode.count == 1 {
@ -756,7 +751,6 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
Logger.statistics.info("📈 [Mesh Statistics] Channel Utilization: \(telemetryMessage.localStats.channelUtilization, privacy: .public) Airtime: \(telemetryMessage.localStats.airUtilTx, privacy: .public) Packets Sent: \(telemetryMessage.localStats.numPacketsTx, privacy: .public) Packets Received: \(telemetryMessage.localStats.numPacketsRx, privacy: .public) Bad Packets Received: \(telemetryMessage.localStats.numPacketsRxBad, privacy: .public) Nodes Online: \(telemetryMessage.localStats.numOnlineNodes, privacy: .public) of \(telemetryMessage.localStats.numTotalNodes, privacy: .public) nodes for Node: \(packet.from.toHex(), privacy: .public)")
} else if telemetryMessage.variant == Telemetry.OneOf_Variant.powerMetrics(telemetryMessage.powerMetrics) {
Logger.data.info("📈 [Power Metrics] Received for Node: \(packet.from.toHex(), privacy: .public)")
telemetry.powerCh1Voltage = telemetryMessage.powerMetrics.hasCh1Voltage.then(telemetryMessage.powerMetrics.ch1Voltage)
telemetry.powerCh1Current = telemetryMessage.powerMetrics.hasCh1Current.then(telemetryMessage.powerMetrics.ch1Current)
telemetry.powerCh2Voltage = telemetryMessage.powerMetrics.hasCh2Voltage.then(telemetryMessage.powerMetrics.ch2Voltage)
@ -764,7 +758,6 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
telemetry.powerCh3Voltage = telemetryMessage.powerMetrics.hasCh3Voltage.then(telemetryMessage.powerMetrics.ch3Voltage)
telemetry.powerCh3Current = telemetryMessage.powerMetrics.hasCh3Current.then(telemetryMessage.powerMetrics.ch3Current)
telemetry.metricsType = 2
}
telemetry.snr = packet.rxSnr
telemetry.rssi = packet.rxRssi
@ -781,7 +774,6 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
fetchedNode[0].telemetries = mutableTelemetries.copy() as? NSOrderedSet
}
try context.save()
Logger.data.info("💾 [TelemetryEntity] of type \(MetricsTypes(rawValue: Int(telemetry.metricsType))?.name ?? "Unknown Metrics Type", privacy: .public) Saved for Node: \(packet.from.toHex(), privacy: .public)")
if telemetry.metricsType == 0 {
// Connected Device Metrics
@ -980,7 +972,7 @@ func textMessageAppPacket(
manager.notifications = [
Notification(
id: ("notification.id.\(newMessage.messageId)"),
title: "\(newMessage.fromUser?.longName ?? "unknown".localized)",
title: "\(newMessage.fromUser?.longName ?? "Unknown".localized)",
subtitle: "AKA \(newMessage.fromUser?.shortName ?? "?")",
content: messageText!,
target: "messages",
@ -992,7 +984,7 @@ func textMessageAppPacket(
)
]
manager.schedule()
Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "unknown".localized, privacy: .public)")
Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "Unknown".localized, privacy: .public)")
}
} else if newMessage.fromUser != nil && newMessage.toUser == nil {
let fetchMyInfoRequest = MyInfoEntity.fetchRequest()
@ -1011,7 +1003,7 @@ func textMessageAppPacket(
manager.notifications = [
Notification(
id: ("notification.id.\(newMessage.messageId)"),
title: "\(newMessage.fromUser?.longName ?? "unknown".localized)",
title: "\(newMessage.fromUser?.longName ?? "Unknown".localized)",
subtitle: "AKA \(newMessage.fromUser?.shortName ?? "?")",
content: messageText!,
target: "messages",
@ -1023,7 +1015,7 @@ func textMessageAppPacket(
)
]
manager.schedule()
Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "unknown".localized, privacy: .public)")
Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "Unknown".localized, privacy: .public)")
}
}
}

View file

@ -43,18 +43,18 @@ class MqttClientProxyManager {
let port = defaultServerPort
let username = node.mqttConfig?.username
let password = node.mqttConfig?.password
// if host == defaultServerAddress {
//username = ProcessInfo.processInfo.environment["PUBLIC_MQTT_USERNAME"]
//password = ProcessInfo.processInfo.environment["PUBLIC_MQTT_PASSWORD"]
// }
let root = node.mqttConfig?.root?.count ?? 0 > 0 ? node.mqttConfig?.root : "msh"
let prefix = root!
topic = prefix + "/2/e" + "/#"
let qos = CocoaMQTTQoS(rawValue: UInt8(1))!
connect(host: host, port: port, useSsl: useSsl, username: username, password: password, topic: topic, qos: qos, cleanSession: true)
// Require opt in to map report terms to connect
if node.mqttConfig?.mapReportingEnabled ?? false && UserDefaults.mapReportingOptIn || !(node.mqttConfig?.mapReportingEnabled ?? false) {
connect(host: host, port: port, useSsl: useSsl, username: username, password: password, topic: topic)
} else {
delegate?.onMqttError(message: "MQTT Map Reporting Terms need to be accepted.")
}
}
}
func connect(host: String, port: Int, useSsl: Bool, username: String?, password: String?, topic: String?, qos: CocoaMQTTQoS, cleanSession: Bool) {
func connect(host: String, port: Int, useSsl: Bool, username: String?, password: String?, topic: String?) {
guard !host.isEmpty else {
delegate?.onMqttDisconnected()
return
@ -67,7 +67,7 @@ class MqttClientProxyManager {
mqttClient.username = username
mqttClient.password = password
mqttClient.keepAlive = 60
mqttClient.cleanSession = cleanSession
mqttClient.cleanSession = true
if debugLog {
mqttClient.logLevel = .debug
}

View file

@ -41,7 +41,6 @@ class MetricsChartSeries: ObservableObject {
// Used for scaling the Y-axis
let initialYAxisRange: ClosedRange<Float>?
let minumumYAxisSpan: Float?
// Main initializer
init<Value, ChartBody: ChartContent, ForegroundStyle: ShapeStyle>(
id: String,

View file

@ -67,12 +67,12 @@ class MetricsSeriesList: ObservableObject, RandomAccessCollection, RangeReplacea
for aSeries in self.visible {
var seriesUpper = range[aSeries]?.upperBound ?? -.infinity
var seriesLower = range[aSeries]?.lowerBound ?? .infinity
if let value = aSeries.valueFor(te) {
// Update the global bounds
if value > globalUpper {globalUpper = value}
if value < globalLower {globalLower = value}
// Update the series bounds if necessary
if value > seriesUpper || value < seriesLower {
if value > seriesUpper {

View file

@ -200,7 +200,7 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
Notification(
id: (UUID().uuidString),
title: "New Node".localized,
subtitle: "\(newUser.longName ?? "unknown".localized)",
subtitle: "\(newUser.longName ?? "Unknown".localized)",
content: "New Node has been discovered".localized,
target: "nodes",
path: "meshtastic:///nodes?nodenum=\(newUser.num)"

View file

@ -13,7 +13,7 @@ struct MessagesTip: Tip {
return "tip.messages"
}
var title: Text {
Text("tip.messages.title")
Text("Messages")
}
var message: Text? {
Text("tip.messages.message")

View file

@ -64,10 +64,10 @@ struct Connect: View {
if node != nil {
Text(connectedPeripheral.longName.addingVariationSelectors).font(.title2)
}
Text("BLE Name").font(.callout)+Text(": \(bleManager.connectedPeripheral?.peripheral.name?.addingVariationSelectors ?? "unknown".localized)")
Text("BLE Name").font(.callout)+Text(": \(bleManager.connectedPeripheral?.peripheral.name?.addingVariationSelectors ?? "Unknown".localized)")
.font(.callout).foregroundColor(Color.gray)
if node != nil {
Text("firmware.version").font(.callout)+Text(": \(node?.metadata?.firmwareVersion ?? "unknown".localized)")
Text("Firmware Version").font(.callout)+Text(": \(node?.metadata?.firmwareVersion ?? "Unknown".localized)")
.font(.callout).foregroundColor(Color.gray)
}
if bleManager.isSubscribed {
@ -121,7 +121,7 @@ struct Connect: View {
#endif
Text("Num: \(String(node!.num))")
Text("Short Name: \(node?.user?.shortName ?? "?")")
Text("Long Name: \(node?.user?.longName?.addingVariationSelectors ?? "unknown".localized)")
Text("Long Name: \(node?.user?.longName?.addingVariationSelectors ?? "Unknown".localized)")
Text("BLE RSSI: \(connectedPeripheral.rssi)")
Button {

View file

@ -49,7 +49,7 @@ struct InvalidVersion: View {
Button {
dismiss()
} label: {
Label("close", systemImage: "xmark")
Label("Close", systemImage: "xmark")
}
.buttonStyle(.bordered)

View file

@ -25,7 +25,7 @@ struct ContentView: View {
unreadDirectMessages: $appState.unreadDirectMessages
)
.tabItem {
Label("messages", systemImage: "message")
Label("Messages", systemImage: "message")
}
.tag(NavigationState.Tab.messages)
.badge(appState.totalUnreadMessages)
@ -54,7 +54,7 @@ struct ContentView: View {
router: appState.router
)
.tabItem {
Label("settings", systemImage: "gear")
Label("Settings", systemImage: "gear")
.font(.title)
}
.tag(NavigationState.Tab.settings)

View file

@ -10,11 +10,11 @@ struct CircleText: View {
var text: String
var color: Color
var circleSize: CGFloat = 45
var node: NodeInfoEntity? = nil
var node: NodeInfoEntity?
var body: some View {
if let node = node {
NavigationStack{
NavigationStack {
NavigationLink(destination: NodeDetail(node: node)) {
circleContent
}

View file

@ -31,7 +31,7 @@ import SwiftUI
WeightCompactWidget(weight: "123", unit: "kg")
SoilTemperatureCompactWidget(temperature: "23", unit: "°C")
SoilMoistureCompactWidget(moisture: "23", unit: "%")
let rain: Float = 10.1
let locale = NSLocale.current as NSLocale
let usesMetricSystem = locale.usesMetricSystem // Returns true for metric (mm), false for imperial (inches)

View file

@ -16,7 +16,7 @@ struct RadiationCompactWidget: View {
HStack(alignment: .firstTextBaseline) {
Text(verbatim: "")
.font(.system(size: 30, design: .monospaced))
.foregroundColor(.accentColor)
.tint(.accentColor)
Text("Radiation")
.textCase(.uppercase)
.font(.callout)

View file

@ -39,4 +39,3 @@ struct WeatherConditionsCompactWidget: View {
}
}
}

View file

@ -24,7 +24,7 @@ struct DateTimeText: View {
if dateTime != nil && dateTime! >= sixMonthsAgo! {
Text(" \(dateTime!.formattedDate(format: dateFormatString))")
} else {
Text("unknown.age")
Text("Unknown Age")
}
}
}

View file

@ -50,7 +50,7 @@ struct DirectMessagesHelp: View {
Button {
dismiss()
} label: {
Label("close", systemImage: "xmark")
Label("Close", systemImage: "xmark")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)

View file

@ -29,7 +29,7 @@ struct MQTTIcon: View {
VStack(spacing: 0.5) {
Text("Topic: \(topic)".localized)
.padding(20)
Button("close", action: { self.isPopoverOpen = false }).padding([.bottom], 20)
Button("Close", action: { self.isPopoverOpen = false }).padding([.bottom], 20)
}
.presentationCompactAdaptation(.popover)
})

View file

@ -69,8 +69,8 @@ struct PowerMetrics: View {
}
enum PowerMetricType: String {
case current = "current"
case voltage = "voltage"
case current = "Current"
case voltage = "Voltage"
}
struct PowerMetricCompactWidget: View {

View file

@ -154,6 +154,6 @@ struct ChannelList: View {
.listStyle(.plain)
}
}
.navigationTitle("channels")
.navigationTitle("Channels")
}
}

View file

@ -14,19 +14,16 @@ struct ChannelMessageList: View {
@EnvironmentObject var appState: AppState
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
// Keyboard State
@FocusState var messageFieldFocused: Bool
@ObservedObject var myInfo: MyInfoEntity
@ObservedObject var channel: ChannelEntity
@State private var replyMessageId: Int64 = 0
@AppStorage("preferredPeripheralNum") private var preferredPeripheralNum = -1
// Scroll state
@State private var showScrollToBottomButton = false
@State private var hasReachedBottom = false
@State private var gotFirstUnreadMessage: Bool = false
@State private var showScrollToBottomButton = false
@State private var hasReachedBottom = false
@State private var gotFirstUnreadMessage: Bool = false
@State private var messageToHighlight: Int64 = 0
@ -82,7 +79,7 @@ struct ChannelMessageList: View {
let isDetectionSensorMessage = message.portNum == Int32(PortNum.detectionSensorApp.rawValue)
if !currentUser && message.fromUser != nil {
Text("\(message.fromUser?.longName ?? "unknown".localized ) (\(message.fromUser?.userId ?? "?"))")
Text("\(message.fromUser?.longName ?? "Unknown".localized ) (\(message.fromUser?.userId ?? "?"))")
.font(.caption)
.foregroundColor(.gray)
.offset(y: 8)
@ -143,7 +140,7 @@ struct ChannelMessageList: View {
.frame(maxWidth: .infinity)
.id(message.messageId)
.onAppear {
if gotFirstUnreadMessage{
if gotFirstUnreadMessage {
if !message.read {
message.read = true
do {
@ -209,7 +206,6 @@ struct ChannelMessageList: View {
showScrollToBottomButton = true
}
}
// Scroll to bottom button
if showScrollToBottomButton {
Button {
@ -241,7 +237,7 @@ struct ChannelMessageList: View {
ToolbarItem(placement: .principal) {
HStack {
CircleText(text: String(channel.index), color: .accentColor, circleSize: 44).fixedSize()
Text(String(channel.name ?? "unknown".localized).camelCaseToWords()).font(.headline)
Text(String(channel.name ?? "Unknown".localized).camelCaseToWords()).font(.headline)
}
}
ToolbarItem(placement: .navigationBarTrailing) {

View file

@ -73,7 +73,6 @@ struct MessageText: View {
} else {
EmptyView()
}
}
.contextMenu {
MessageContextMenuItems(

View file

@ -35,7 +35,7 @@ struct Messages: View {
List(selection: $router.navigationState.messages) {
NavigationLink(value: MessagesNavigationState.channels()) {
Label {
Text("channels")
Text("Channels")
.badge(unreadChannelMessages)
.font(.title2)
.padding()

View file

@ -43,6 +43,21 @@ struct TextMessageField: View {
}
}
ZStack {
TextField("message", text: $typingMessage, axis: .vertical)
.onChange(of: typingMessage) { _, value in
totalBytes = value.utf8.count
// Only mess with the value if it is too big
while totalBytes > Self.maxbytes {
typingMessage = String(typingMessage.dropLast())
totalBytes = typingMessage.utf8.count
}
}
}
Text("Replying to a message")
}
}
ZStack {
TextField("message", text: $typingMessage, axis: .vertical)
.onChange(of: typingMessage) { _, value in

View file

@ -93,7 +93,7 @@ struct UserList: View {
Image(systemName: "lock.open.fill")
.foregroundColor(.yellow)
}
Text(user.longName ?? "unknown".localized)
Text(user.longName ?? "Unknown".localized)
.font(.headline)
.allowsTightening(true)
Spacer()

View file

@ -20,7 +20,6 @@ struct UserMessageList: View {
// View State Items
@ObservedObject var user: UserEntity
@State private var replyMessageId: Int64 = 0
// Scroll state
@State private var showScrollToBottomButton = false
@State private var hasReachedBottom = false
@ -195,7 +194,6 @@ struct UserMessageList: View {
showScrollToBottomButton = true
}
}
// Scroll to bottom button
if showScrollToBottomButton {
Button {

View file

@ -121,7 +121,7 @@ struct DeviceMetricsLog: View {
Table(deviceMetrics, selection: $selection, sortOrder: $sortOrder) {
TableColumn("Battery Level") { dm in
HStack {
Text(dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
Text(dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized)
.font(.caption)
.fontWeight(.semibold)
Spacer()
@ -165,7 +165,7 @@ struct DeviceMetricsLog: View {
// dm.voltage.map { Text("\(String(format: "%.2f", $0))") } ?? Text("--")
Text("\(dm.voltage?.formatted(.number.precision(.fractionLength(2))) ?? Constants.nilValueIndicator)")
}
TableColumn("channel.utilization") { dm in
TableColumn("Channel Utilization") { dm in
dm.channelUtilization.map { channelUtilization in
// Text("\(String(format: "%.2f", channelUtilization))%")
Text("\(channelUtilization.formatted(.number.precision(.fractionLength(2))))%")
@ -188,7 +188,7 @@ struct DeviceMetricsLog: View {
}
.width(min: 100)
TableColumn("Timestamp") { dm in
Text(dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
Text(dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized)
}
.width(min: 180)
}

View file

@ -49,7 +49,7 @@ struct DeleteNodeButton: View {
connectedNodeNum: connectedNode.num
)
if !success {
Logger.data.error("Failed to delete node \(deleteNode.user?.longName ?? "unknown".localized, privacy: .public)")
Logger.data.error("Failed to delete node \(deleteNode.user?.longName ?? "Unknown".localized, privacy: .public)")
} else {
dismiss()
}

View file

@ -14,45 +14,43 @@ struct NavigateToButton: View {
var node: NodeInfoEntity
var body: some View {
Button {
guard let userNum = node.user?.num else {
Logger.services.error("NavigateToAction: Selected node does not exist")
Button {
guard let userNum = node.user?.num else {
Logger.services.error("NavigateToAction: Selected node does not exist")
return
}
Logger.services.info("Fetching NodeInfoEntity for userNum: \(userNum, privacy: .public)")
let fetchRequest: NSFetchRequest<NodeInfoEntity> = NSFetchRequest(entityName: "NodeInfoEntity")
fetchRequest.predicate = NSPredicate(format: "num == %lld", Int64(userNum))
do {
let fetchedNodes = try PersistenceController.shared.container.viewContext.fetch(fetchRequest)
guard let nodeInfo = fetchedNodes.first else {
Logger.services.error("NavigateToAction: Node with userNum \(userNum, privacy: .public) not found in Core Data")
return
}
Logger.services.info("Fetching NodeInfoEntity for userNum: \(userNum, privacy: .public)")
let fetchRequest: NSFetchRequest<NodeInfoEntity> = NSFetchRequest(entityName: "NodeInfoEntity")
fetchRequest.predicate = NSPredicate(format: "num == %lld", Int64(userNum))
do {
let fetchedNodes = try PersistenceController.shared.container.viewContext.fetch(fetchRequest)
guard let nodeInfo = fetchedNodes.first else {
Logger.services.error("NavigateToAction: Node with userNum \(userNum, privacy: .public) not found in Core Data")
return
}
if let latitude = nodeInfo.latestPosition?.latitude,
let longitude = nodeInfo.latestPosition?.longitude {
if let url = URL(string: "maps://?saddr=&daddr=\(latitude),\(longitude)") {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
Logger.services.error("Failed to create URL for navigation")
}
if let latitude = nodeInfo.latestPosition?.latitude,
let longitude = nodeInfo.latestPosition?.longitude {
if let url = URL(string: "maps://?saddr=&daddr=\(latitude),\(longitude)") {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
Logger.services.warning("NavigateToAction: Node \(userNum, privacy: .public) has invalid or missing coordinates")
Logger.services.error("Failed to create URL for navigation")
}
} catch {
Logger.services.error("NavigateToAction: Failed to fetch node with userNum \(userNum, privacy: .public): \(error.localizedDescription, privacy: .public)")
}
} label: {
Label {
Text("Navigate to node")
} icon: {
Image(systemName: "map")
.symbolRenderingMode(.hierarchical)
} else {
Logger.services.warning("NavigateToAction: Node \(userNum, privacy: .public) has invalid or missing coordinates")
}
} catch {
Logger.services.error("NavigateToAction: Failed to fetch node with userNum \(userNum, privacy: .public): \(error.localizedDescription, privacy: .public)")
}
} label: {
Label {
Text("Navigate to node")
} icon: {
Image(systemName: "map")
.symbolRenderingMode(.hierarchical)
}
}
}
}

View file

@ -111,7 +111,7 @@ Spacer()
Button {
dismiss()
} label: {
Label("close", systemImage: "xmark")
Label("Close", systemImage: "xmark")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)

View file

@ -189,7 +189,7 @@ struct NodeMapSwiftUI: View {
UIApplication.shared.isIdleTimerDisabled = false
}
}}
.navigationBarTitle(String((node.user?.shortName ?? "unknown".localized) + (" \(node.positions?.count ?? 0) points")), displayMode: .inline)
.navigationBarTitle(String((node.user?.shortName ?? "Unknown".localized) + (" \(node.positions?.count ?? 0) points")), displayMode: .inline)
.navigationBarItems(trailing:
ZStack {
ConnectedDevice(

View file

@ -23,7 +23,7 @@ struct PositionPopover: View {
var body: some View {
// Node Color from node.num
let nodeColor = UIColor(hex: UInt32(position.nodePosition?.num ?? 0))
NavigationStack{
NavigationStack {
VStack {
HStack {
ZStack {
@ -105,7 +105,6 @@ struct PositionPopover: View {
.foregroundColor(.primary)
.font(idiom == .phone ? .callout : .body)
}
} icon: {
Image(systemName: "mountain.2.fill")
.symbolRenderingMode(.hierarchical)
@ -180,7 +179,6 @@ struct PositionPopover: View {
}
.padding(.bottom, 5)
if position.nodePosition?.viaMqtt ?? false {
Label {
Text("MQTT")
.font(idiom == .phone ? .callout : .body)
@ -234,7 +232,7 @@ struct PositionPopover: View {
Button {
dismiss()
} label: {
Label("close", systemImage: "xmark")
Label("Close", systemImage: "xmark")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)

View file

@ -338,7 +338,7 @@ struct WaypointForm: View {
if LocationsHandler.currentLocation.distance(from: LocationsHandler.DefaultLocation) > 0.0 {
let metersAway = waypoint.coordinate.distance(from: LocationsHandler.currentLocation)
Label {
Text("distance".localized + ": \(distanceFormatter.string(fromDistance: Double(metersAway)))")
Text("Distance".localized + ": \(distanceFormatter.string(fromDistance: Double(metersAway)))")
.foregroundColor(.primary)
} icon: {
Image(systemName: "lines.measurement.horizontal")
@ -354,7 +354,7 @@ struct WaypointForm: View {
Button {
dismiss()
} label: {
Label("close", systemImage: "xmark")
Label("Close", systemImage: "xmark")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)

View file

@ -220,7 +220,6 @@ extension MetricsColumnList {
)
} ?? Text(Constants.nilValueIndicator)
}),
// Rainfall 24-hour
MetricsTableColumn(
id: "rainfall24H",
@ -334,7 +333,7 @@ extension MetricsColumnList {
.replacingOccurrences(of: ",", with: "")
Text(
time?.formattedDate(format: dateFormatString)
?? "unknown.age".localized
?? "Unknown Age".localized
)
})
])

View file

@ -80,7 +80,7 @@ extension MetricsSeriesList {
.alignsMarkStylesWithPlotArea()
}
}),
// Barometric Pressure Series Configuration
MetricsChartSeries(
id: "barometricPressure",
@ -106,7 +106,7 @@ extension MetricsSeriesList {
.alignsMarkStylesWithPlotArea()
}
}),
// Indoor Air Quality Series Configuration
MetricsChartSeries(
id: "iaq",
@ -134,7 +134,7 @@ extension MetricsSeriesList {
.alignsMarkStylesWithPlotArea()
}
}),
// Lux
MetricsChartSeries(
id: "lux",
@ -460,7 +460,7 @@ extension MetricsSeriesList {
.lineStyle(StrokeStyle(lineWidth: 4))
.alignsMarkStylesWithPlotArea()
}
}),
})
])
}
}

View file

@ -63,7 +63,7 @@ struct MetricsColumnDetail: View {
Button {
dismiss()
} label: {
Label("close", systemImage: "xmark")
Label("Close", systemImage: "xmark")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)

View file

@ -120,14 +120,14 @@ struct NodeDetail: View {
if let metadata = node.metadata {
HStack {
Label {
Text("firmware.version")
Text("Firmware Version")
} icon: {
Image(systemName: "memorychip")
.symbolRenderingMode(.multicolor)
}
Spacer()
Text(metadata.firmwareVersion ?? "unknown".localized)
Text(metadata.firmwareVersion ?? "Unknown".localized)
}
}
@ -147,7 +147,7 @@ struct NodeDetail: View {
if let dm = node.telemetries?.filtered(using: NSPredicate(format: "metricsType == 0")).lastObject as? TelemetryEntity, let uptimeSeconds = dm.uptimeSeconds {
HStack {
Label {
Text("\("uptime".localized)")
Text("\("Uptime".localized)")
} icon: {
Image(systemName: "checkmark.circle.fill")
.foregroundColor(.green)
@ -195,7 +195,7 @@ struct NodeDetail: View {
Spacer()
if dateFormatRelative, let text = Self.relativeFormatter.string(for: lastHeard) {
if lastHeard.formatted() != "unknown.age".localized {
if lastHeard.formatted() != "Unknown Age".localized {
Text(text)
.textSelection(.enabled)
}
@ -214,7 +214,7 @@ struct NodeDetail: View {
// to use with WeatherKit, or has actual data in the most recent EnvironmentMetrics entity
// that will be rendered in this section.
if node.hasPositions && UserDefaults.environmentEnableWeatherKit
|| node.hasDataForLatestEnvironmentMetrics(attributes: ["iaq", "temperature", "relativeHumidity", "barometricPressure", "windSpeed", "radiation", "weight", "distance", "soilTemperature", "soilMoisture"]) {
|| node.hasDataForLatestEnvironmentMetrics(attributes: ["iaq", "temperature", "relativeHumidity", "barometricPressure", "windSpeed", "radiation", "weight", "Distance", "soilTemperature", "soilMoisture"]) {
Section("Environment") {
if !node.hasEnvironmentMetrics {
LocalWeatherConditions(location: node.latestPosition?.nodeLocation)
@ -520,7 +520,7 @@ struct NodeDetail: View {
}
}
.listStyle(.insetGrouped)
.navigationBarTitle(String(node.user?.longName?.addingVariationSelectors ?? "unknown".localized), displayMode: .inline)
.navigationBarTitle(String(node.user?.longName?.addingVariationSelectors ?? "Unknown".localized), displayMode: .inline)
}
}
}

View file

@ -74,7 +74,7 @@ struct NodeInfoItem: View {
}
Spacer()
if user.hwModel != "UNSET" {
Text(String(node.user?.hwDisplayName ?? (node.user?.hwModel ?? "unset".localized)))
Text(String(node.user?.hwDisplayName ?? (node.user?.hwModel ?? "Unset".localized)))
} else {
Text(String("incomplete".localized))
}

View file

@ -192,7 +192,7 @@ struct NodeListFilter: View {
Button {
dismiss()
} label: {
Label("close", systemImage: "xmark")
Label("Close", systemImage: "xmark")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)

View file

@ -64,7 +64,7 @@ struct NodeListItem: View {
let (image, color) = userKeyStatus
IconAndText(systemName: image,
imageColor: color,
text: node.user?.longName?.addingVariationSelectors ?? "unknown".localized,
text: node.user?.longName?.addingVariationSelectors ?? "Unknown".localized,
textColor: .primary)
if node.favorite {
Spacer()
@ -77,14 +77,14 @@ struct NodeListItem: View {
imageColor: .green,
text: "connected".localized)
}
if node.lastHeard?.timeIntervalSince1970 ?? 0 > 0 && node.lastHeard! < Calendar.current.date(byAdding: .year, value: 1, to: Date())!{
if node.lastHeard?.timeIntervalSince1970 ?? 0 > 0 && node.lastHeard! < Calendar.current.date(byAdding: .year, value: 1, to: Date())! {
IconAndText(systemName: node.isOnline ? "checkmark.circle.fill" : "moon.circle.fill",
imageColor: node.isOnline ? .green : .orange,
text: node.lastHeard?.formatted() ?? "unknown.age".localized)
text: node.lastHeard?.formatted() ?? "Unknown Age".localized)
}
let role = DeviceRoles(rawValue: Int(node.user?.role ?? 0))
IconAndText(systemName: role?.systemName ?? "figure",
text: "Role: \(role?.name ?? "unknown".localized)")
text: "Role: \(role?.name ?? "Unknown".localized)")
if node.isStoreForwardRouter {
IconAndText(systemName: "envelope.arrow.triangle.branch",
renderingMode: .multicolor,

View file

@ -65,10 +65,7 @@ struct NodeList: View {
var nodes: FetchedResults<NodeInfoEntity>
var connectedNode: NodeInfoEntity? {
getNodeInfo(
id: bleManager.connectedPeripheral?.num ?? 0,
context: context
)
getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context)
}
@ViewBuilder
@ -78,19 +75,11 @@ struct NodeList: View {
) -> some View {
/// Allow users to mute notifications for a node even if they are not connected
if let user = node.user {
NodeAlertsButton(
context: context,
node: node,
user: user
)
NodeAlertsButton(context: context, node: node, user: user)
}
if let connectedNode {
/// Favoriting a node requires being connected
FavoriteNodeButton(
bleManager: bleManager,
context: context,
node: node
)
FavoriteNodeButton(bleManager: bleManager, context: context, node: node)
/// Don't show message, trace route, position exchange or delete context menu items for the connected node
if connectedNode.num != node.num {
if !node.viaMqtt || node.viaMqtt && node.hopsAway == 0 {
@ -237,7 +226,7 @@ struct NodeList: View {
if deleteNode != nil {
let success = bleManager.removeNode(node: deleteNode!, connectedNodeNum: Int64(bleManager.connectedPeripheral?.num ?? -1))
if !success {
Logger.data.error("Failed to delete node \(deleteNode?.user?.longName ?? "unknown".localized, privacy: .public)")
Logger.data.error("Failed to delete node \(deleteNode?.user?.longName ?? "Unknown".localized, privacy: .public)")
}
}
}

View file

@ -1,233 +0,0 @@
////
//// NodeMap.swift
//// MeshtasticApple
////
//// Created by Garth Vander Houwen on 8/7/21.
////
//
//import SwiftUI
//import MapKit
//import CoreLocation
//import CoreData
//
//struct NodeMap: View {
// @Environment(\.managedObjectContext) var context
// @EnvironmentObject var bleManager: BLEManager
//
// @ObservedObject
// var router: Router
// @State var selectedMapLayer: MapLayer = UserDefaults.mapLayer
// @State var enableMapRecentering: Bool = UserDefaults.enableMapRecentering
// @State var enableMapRouteLines: Bool = UserDefaults.enableMapRouteLines
// @State var enableMapNodeHistoryPins: Bool = UserDefaults.enableMapNodeHistoryPins
// @State var enableOfflineMaps: Bool = UserDefaults.enableOfflineMaps
// @State var selectedTileServer: MapTileServer = UserDefaults.mapTileServer
// @State var enableOverlayServer: Bool = UserDefaults.enableOverlayServer
// @State var selectedOverlayServer: MapOverlayServer = UserDefaults.mapOverlayServer
// @State var mapTilesAboveLabels: Bool = UserDefaults.mapTilesAboveLabels
// let fromDate: NSDate = Calendar.current.date(byAdding: .month, value: -1, to: Date())! as NSDate
// @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "time", ascending: true)],
// predicate: NSPredicate(format: "nodePosition != nil", Calendar.current.date(byAdding: .day, value: -7, to: Date())! as NSDate), animation: .none)
// private var positions: FetchedResults<PositionEntity>
// @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "name", ascending: false)],
// predicate: NSPredicate(
// format: "expire == nil || expire >= %@", Date() as NSDate
// ), animation: .none)
// private var waypoints: FetchedResults<WaypointEntity>
// @State var waypointCoordinate: WaypointCoordinate?
// @State var selectedTracking: UserTrackingModes = .none
// @State var isPresentingInfoSheet: Bool = false
// @State private var customMapOverlay: MapViewSwiftUI.CustomMapOverlay? = MapViewSwiftUI.CustomMapOverlay(
// mapName: "offlinemap",
// tileType: "png",
// canReplaceMapContent: true
// )
// var body: some View {
// NavigationStack {
// ZStack {
// MapViewSwiftUI(
// onLongPress: { coord in
// waypointCoordinate = WaypointCoordinate(id: .init(), coordinate: coord, waypointId: 0)
// }, onWaypointEdit: { wpId in
// if wpId > 0 {
// waypointCoordinate = WaypointCoordinate(id: .init(), coordinate: nil, waypointId: Int64(wpId))
// }
// },
// selectedMapLayer: selectedMapLayer,
// positions: Array(positions),
// waypoints: Array(waypoints),
// userTrackingMode: selectedTracking.MKUserTrackingModeValue(),
// showNodeHistory: enableMapNodeHistoryPins,
// showRouteLines: enableMapRouteLines,
// customMapOverlay: self.customMapOverlay
// )
// VStack(alignment: .trailing) {
// HStack(alignment: .top) {
// Spacer()
// MapButtons(tracking: $selectedTracking, isPresentingInfoSheet: $isPresentingInfoSheet)
// .padding(.trailing, 8)
// .padding(.top, 16)
// }
// Spacer()
// TileDownloadStatus()
// .padding(.trailing, 16)
// .padding(.bottom, 20)
// }
// }
// .ignoresSafeArea(.all, edges: [.top, .leading, .trailing])
// .frame(maxHeight: .infinity)
// .sheet(item: $waypointCoordinate, content: { wpc in
// WaypointFormMapKit(coordinate: wpc)
// .presentationDetents([.medium, .large])
// .presentationDragIndicator(.automatic)
// })
// .sheet(isPresented: $isPresentingInfoSheet) {
// VStack {
// Form {
// Section(header: Text("Map Options")) {
// Picker(selection: $selectedMapLayer, label: Text("")) {
// ForEach(MapLayer.allCases, id: \.self) { layer in
// if layer == MapLayer.offline && enableOfflineMaps {
// Text(layer.localized)
// } else if layer != MapLayer.offline {
// Text(layer.localized)
// }
// }
// }
// .pickerStyle(SegmentedPickerStyle())
// .onChange(of: selectedMapLayer) { _, newMapLayer in
// UserDefaults.mapLayer = newMapLayer
// }
// .padding(.top, 5)
// .padding(.bottom, 5)
// Toggle(isOn: $enableMapRecentering) {
// Label("map.recentering", systemImage: "camera.metering.center.weighted")
// }
// .toggleStyle(SwitchToggleStyle(tint: .accentColor))
// .onTapGesture {
// self.enableMapRecentering.toggle()
// UserDefaults.enableMapRecentering = self.enableMapRecentering
// }
// Toggle(isOn: $enableMapNodeHistoryPins) {
// Label("Show Node History", systemImage: "building.columns.fill")
// }
// .toggleStyle(SwitchToggleStyle(tint: .accentColor))
// .onTapGesture {
// self.enableMapNodeHistoryPins.toggle()
// UserDefaults.enableMapNodeHistoryPins = self.enableMapNodeHistoryPins
// }
// Toggle(isOn: $enableMapRouteLines) {
// Label("Show Route Lines", systemImage: "road.lanes")
// }
// .toggleStyle(SwitchToggleStyle(tint: .accentColor))
// .onTapGesture {
// self.enableMapRouteLines.toggle()
// UserDefaults.enableMapRouteLines = self.enableMapRouteLines
// }
// let locale = Locale.current
// if locale.region?.identifier ?? "no locale" == "US" {
// Toggle(isOn: $enableOverlayServer) {
// Label("Show Weather", systemImage: "cloud.fill")
// }
// .toggleStyle(SwitchToggleStyle(tint: .accentColor))
// .onTapGesture {
// self.enableOverlayServer.toggle()
// UserDefaults.enableOverlayServer = self.enableOverlayServer
// }
// if enableOverlayServer {
// Picker(selection: $selectedOverlayServer,
// label: Text("Radar")) {
// ForEach(MapOverlayServer.allCases, id: \.self) { mos in
// Text(mos.description)
// .font(.footnote)
// }
// }
// .pickerStyle(DefaultPickerStyle())
// .onChange(of: (selectedOverlayServer)) { _, newSelectedOverlayServer in
// UserDefaults.mapOverlayServer = newSelectedOverlayServer
// }
// Text(LocalizedStringKey(selectedOverlayServer.attribution))
// .font(.footnote)
// .foregroundColor(.gray)
// .padding(0)
// }
// }
// }
// Section(header: Text("Offline Maps")) {
// Toggle(isOn: $enableOfflineMaps) {
// Text("Enable Offline Maps")
// }
// .toggleStyle(SwitchToggleStyle(tint: .accentColor))
// .onChange(of: enableOfflineMaps) { _, newEnableOfflineMaps in
// UserDefaults.enableOfflineMaps = newEnableOfflineMaps
// if !enableOfflineMaps {
// if self.selectedMapLayer == .offline {
// self.selectedMapLayer = .standard
// }
// }
// }
// if enableOfflineMaps {
// VStack(alignment: .leading) {
// Picker(selection: $selectedTileServer,
// label: Text("Tile Server")) {
// ForEach(MapTileServer.allCases, id: \.self) { tsl in
// Text(tsl.description)
// }
// }
// .pickerStyle(DefaultPickerStyle())
// .onChange(of: (selectedTileServer)) { _, newSelectedTileServer in
// UserDefaults.mapTileServer = newSelectedTileServer
// }
// Text("Attribution:")
// .fontWeight(.semibold)
// .font(.footnote)
// Text(LocalizedStringKey(selectedTileServer.attribution))
// .font(.footnote)
// .foregroundColor(.gray)
// .padding(0)
// Divider()
// Toggle(isOn: $mapTilesAboveLabels) {
// Text("Tiles above Labels")
// }
// .toggleStyle(SwitchToggleStyle(tint: .accentColor))
// .onTapGesture {
// self.mapTilesAboveLabels.toggle()
// UserDefaults.mapTilesAboveLabels = self.mapTilesAboveLabels
// }
// }
// }
// }
// }
// #if targetEnvironment(macCatalyst)
// Button {
// isPresentingInfoSheet = false
// } label: {
// Label("close", systemImage: "xmark")
// }
// .buttonStyle(.bordered)
// .buttonBorderShape(.capsule)
// .controlSize(.large)
// .padding(.bottom)
// #endif
// }
// .presentationDetents([enableOfflineMaps || enableOverlayServer ? .large : .medium])
// .presentationDragIndicator(.visible)
// }
// }
// .navigationBarItems(leading:
// MeshtasticLogo(), trailing:
// ZStack {
// ConnectedDevice(
// bluetoothOn: bleManager.isSwitchedOn,
// deviceConnected: bleManager.connectedPeripheral != nil,
// name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName :
// "?")
// })
// .onAppear(perform: {
// UIApplication.shared.isIdleTimerDisabled = true
// })
// .onDisappear(perform: {
// UIApplication.shared.isIdleTimerDisabled = false
// })
// }
//}

View file

@ -98,14 +98,14 @@ struct PaxCounterLog: View {
TableColumn("paxcounter.total") { pc in
Text("\(pc.wifi + pc.ble)")
}
TableColumn("uptime") { pc in
TableColumn("Uptime") { pc in
let now = Date.now
let later = now + TimeInterval(pc.uptime)
let components = (now..<later).formatted(.components(style: .condensedAbbreviated))
Text(components)
}
TableColumn("Timestamp") { pc in
Text(pc.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
Text(pc.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized)
}
.width(min: 180)
}
@ -149,7 +149,7 @@ struct PaxCounterLog: View {
let components = (now..<later).formatted(.components(style: .condensedAbbreviated))
Text(components)
.font(.caption)
Text(pc.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
Text(pc.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized)
.font(.caption)
}
}

View file

@ -60,13 +60,11 @@ struct PositionLog: View {
Text("\(String(format: "%.2f", position.snr)) dB")
}
TableColumn("Time Stamp") { position in
Text(position.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
Text(position.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized)
}
.width(min: 180)
}
.textSelection(.enabled)
} else {
ScrollView {
// Use a grid on iOS as a table only shows a single column
@ -107,7 +105,7 @@ struct PositionLog: View {
.font(.caption2)
Text(altitude.formatted())
.font(.caption2)
Text(mappin.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
Text(mappin.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized)
.font(.caption2)
}
}

View file

@ -122,7 +122,7 @@ struct PowerMetricsLog: View {
Table(powerMetrics, selection: $selection, sortOrder: $sortOrder) {
TableColumn("Timestamp") { m in
HStack {
Text(m.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
Text(m.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized)
Spacer()
HStack {
VStack {
@ -213,7 +213,7 @@ struct PowerMetricsLog: View {
}
.width(min: 75)
TableColumn("Timestamp") { dm in
Text(dm.time?.formattedDate(format: dateFormatString) ?? "unknown.age".localized)
Text(dm.time?.formattedDate(format: dateFormatString) ?? "Unknown Age".localized)
}
.width(min: 180)

View file

@ -37,14 +37,14 @@ struct TraceRouteLog: View {
VStack {
List(node.traceRoutes?.reversed() as? [TraceRouteEntity] ?? [], id: \.self, selection: $selectedRoute) { route in
Label {
let routeTime = route.time?.formatted() ?? "unknown".localized
let routeTime = route.time?.formatted() ?? "Unknown".localized
if route.response && route.hopsTowards == route.hopsBack {
let hopString = String(localized: "\(route.hopsTowards) Hops")
Text("\(routeTime) - \(hopString)")
.font(.caption)
} else if route.response {
let hopTowardsString = String(localized: "\(route.hopsTowards) Hops")
let hopBackString = route.hopsBack >= 0 ? String(localized: "\(route.hopsBack) Hops") : String(localized: "unknown")
let hopBackString = route.hopsBack >= 0 ? String(localized: "\(route.hopsBack) Hops") : String(localized: "Unknown")
Text("\(routeTime) - \(hopTowardsString) Towards \(hopBackString) Back")
.font(.caption)
} else if route.sent {
@ -78,14 +78,14 @@ struct TraceRouteLog: View {
if selectedRoute != nil {
if selectedRoute?.response ?? false && selectedRoute?.hopsTowards ?? 0 >= 0 {
Label {
Text("Route: \(selectedRoute?.routeText ?? "unknown".localized)")
Text("Route: \(selectedRoute?.routeText ?? "Unknown".localized)")
} icon: {
Image(systemName: "signpost.right")
.symbolRenderingMode(.hierarchical)
}
.font(.title3)
Label {
Text("Route Back: \(selectedRoute?.routeBackText ?? "unknown".localized)")
Text("Route Back: \(selectedRoute?.routeBackText ?? "Unknown".localized)")
} icon: {
Image(systemName: "signpost.left")
.symbolRenderingMode(.hierarchical)
@ -94,7 +94,7 @@ struct TraceRouteLog: View {
} else if !(selectedRoute?.sent ?? true) {
Label {
VStack {
Text("Trace route to \(selectedRoute?.node?.user?.longName ?? "unknown".localized) was not sent.")
Text("Trace route to \(selectedRoute?.node?.user?.longName ?? "Unknown".localized) was not sent.")
.font(idiom == .phone ? .body : .largeTitle)
.fontWeight(.semibold)
Text("Trace Route was rate limited. You can send a trace route a maximum of once every thirty seconds.")
@ -109,7 +109,7 @@ struct TraceRouteLog: View {
} else {
Label {
VStack {
Text("Trace route sent to \(selectedRoute?.node?.user?.longName ?? "unknown".localized)")
Text("Trace route sent to \(selectedRoute?.node?.user?.longName ?? "Unknown".localized)")
.font(idiom == .phone ? .body : .largeTitle)
.fontWeight(.semibold)
Text("A Trace Route was sent, no response has been received.")

View file

@ -14,7 +14,6 @@ struct AboutMeshtastic: View {
var body: some View {
VStack {
List {
Section(header: Text("What is Meshtastic?")) {
Text("An open source, off-grid, decentralized, mesh network that runs on affordable, low-power radios.")
@ -44,7 +43,7 @@ struct AboutMeshtastic: View {
Button("Review the app") {
if let scene = UIApplication.shared.connectedScenes
.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
SKStoreReviewController.requestReview(in: scene)
AppStore.requestReview(in: scene)
}
}
.font(.title2)

View file

@ -35,7 +35,7 @@ struct AppLog: View {
if idiom == .phone {
Table(logs, selection: $selection, sortOrder: $sortOrder) {
TableColumn("log.message", value: \.composedMessage) { value in
TableColumn("Message", value: \.composedMessage) { value in
Text(value.composedMessage)
.foregroundStyle(value.level.color)
.font(.caption)
@ -86,7 +86,7 @@ struct AppLog: View {
.width(min: 85, max: 110)
TableColumn("log.category", value: \.category)
.width(min: 80, max: 130)
TableColumn("log.message", value: \.composedMessage) { value in
TableColumn("Message", value: \.composedMessage) { value in
Text(value.composedMessage)
.foregroundStyle(value.level.color)
.font(.body)
@ -270,4 +270,4 @@ extension AppLog {
}
}
extension OSLogEntry: Identifiable { }
extension OSLogEntry: @retroactive Identifiable { }

View file

@ -43,7 +43,7 @@ struct AppSettings: View {
Button {
isPresentingCoreDataResetConfirm = true
} label: {
Label("clear.app.data", systemImage: "trash")
Label("Clear App Data", systemImage: "trash")
.foregroundColor(.red)
}
.confirmationDialog(

View file

@ -230,7 +230,7 @@ struct Channels: View {
Button {
goBack()
} label: {
Label("close", systemImage: "xmark")
Label("Close", systemImage: "xmark")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)
@ -279,7 +279,7 @@ struct Channels: View {
.padding()
}
}
.navigationTitle("channels")
.navigationTitle("Channels")
.navigationBarItems(trailing:
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")

View file

@ -30,7 +30,7 @@ struct ChannelForm: View {
Form {
Section(header: Text("channel details")) {
HStack {
Text("name")
Text("Name")
Spacer()
TextField(
"Channel Name",
@ -128,7 +128,7 @@ struct ChannelForm: View {
}
}
Section(header: Text("position")) {
Section(header: Text("Position")) {
VStack(alignment: .leading) {
Toggle(isOn: $positionsEnabled) {
Label(channelRole == 1 ? "Positions Enabled" : "Allow Position Requests", systemImage: positionsEnabled ? "mappin" : "mappin.slash")
@ -170,7 +170,7 @@ struct ChannelForm: View {
}
}
}
Section(header: Text("mqtt")) {
Section(header: Text("MQTT")) {
Toggle(isOn: $uplink) {
Label("Uplink Enabled", systemImage: "arrowshape.up")
}

View file

@ -30,11 +30,9 @@ struct DeviceConfig: View {
@State var ledHeartbeatEnabled = true
@State var tripleClickAsAdHocPing = true
@State var tzdef = ""
@State private var showRouterWarning = false
@State private var confirmWarning = false
var body: some View {
VStack {
Form {
@ -149,7 +147,7 @@ struct DeviceConfig: View {
Picker("Button GPIO", selection: $buttonGPIO) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}
@ -159,7 +157,7 @@ struct DeviceConfig: View {
Picker("Buzzer GPIO", selection: $buzzerGPIO) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}

View file

@ -153,7 +153,7 @@ struct DisplayConfig: View {
}
}
.navigationTitle("display.config")
.navigationTitle("Display Config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(

View file

@ -103,7 +103,7 @@ struct CannedMessagesConfig: View {
Picker("Pin A", selection: $inputbrokerPinA) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}
@ -118,7 +118,7 @@ struct CannedMessagesConfig: View {
Picker("Pin B", selection: $inputbrokerPinB) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}
@ -133,7 +133,7 @@ struct CannedMessagesConfig: View {
Picker("Press Pin", selection: $inputbrokerPinPress) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}

View file

@ -108,7 +108,7 @@ struct DetectionSensorConfig: View {
Picker("GPIO Pin to monitor", selection: $monitorPin) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}

View file

@ -82,7 +82,7 @@ struct ExternalNotificationConfig: View {
Picker("Output pin GPIO", selection: $output) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}
@ -138,7 +138,7 @@ struct ExternalNotificationConfig: View {
Picker("Output pin buzzer GPIO ", selection: $outputBuzzer) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}
@ -148,7 +148,7 @@ struct ExternalNotificationConfig: View {
Picker("Output pin vibra GPIO", selection: $outputVibra) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}

View file

@ -30,8 +30,8 @@ struct MQTTConfig: View {
@State var mqttConnected: Bool = false
@State var defaultTopic = "msh/US"
@State var nearbyTopics = [String]()
@State var mapReportingOptIn = false
@State var mapReportingEnabled = false
@AppStorage("mapReportingOptIn") private var mapReportingOptIn: Bool = false
@State var mapPublishIntervalSecs = 3600
@State var mapPositionPrecision: Double = 14.0
@ -266,7 +266,7 @@ struct MQTTConfig: View {
mqtt.encryptionEnabled = self.encryptionEnabled
mqtt.jsonEnabled = self.jsonEnabled
mqtt.tlsEnabled = self.tlsEnabled
mqtt.mapReportingEnabled = (self.mapReportingEnabled && self.mapReportingOptIn)
mqtt.mapReportingEnabled = self.mapReportingEnabled
mqtt.mapReportSettings.positionPrecision = UInt32(self.mapPositionPrecision)
mqtt.mapReportSettings.publishIntervalSecs = UInt32(self.mapPublishIntervalSecs)
let adminMessageId = bleManager.saveMQTTConfig(config: mqtt, fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
@ -388,7 +388,6 @@ struct MQTTConfig: View {
}
if let placemarks = placemarks, let placemark = placemarks.first {
let cc = locale.region?.identifier ?? "UNK"
/// Country Topic unless your region is a country
if !(region?.isCountry ?? false) {
let countryTopic = defaultTopic + "/" + (placemark.isoCountryCode ?? "")

View file

@ -27,12 +27,12 @@ struct PaxCounterConfig: View {
Section {
Toggle(isOn: $enabled) {
Label("Enabled", systemImage: "figure.walk.motion")
Text("config.module.paxcounter.enabled.description")
Text("When enabled the PAX Counter module counts the number of people passing by using WiFi and Bluetooth. Both WiFI and Bluetooth must be disabled for PAX counter to work.")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
.listRowSeparator(.visible)
if enabled {
Picker("config.module.paxcounter.updateinterval", selection: $paxcounterUpdateInterval) {
Picker("Update Interval", selection: $paxcounterUpdateInterval) {
ForEach(UpdateIntervals.allCases) { at in
if at.rawValue >= 300 {
Text(at.description)

View file

@ -41,7 +41,7 @@ struct SerialConfig: View {
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Toggle(isOn: $echo) {
Label("echo", systemImage: "repeat")
Label("Echo", systemImage: "repeat")
Text("If set, any packets you send will be echoed back to your device.")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
@ -53,7 +53,7 @@ struct SerialConfig: View {
}
.pickerStyle(DefaultPickerStyle())
.listRowSeparator(/*@START_MENU_TOKEN@*/.visible/*@END_MENU_TOKEN@*/)
Picker("timeout", selection: $timeout ) {
Picker("Timeout", selection: $timeout ) {
ForEach(SerialTimeoutIntervals.allCases) { sti in
Text(sti.description)
}
@ -64,7 +64,7 @@ struct SerialConfig: View {
.foregroundColor(.gray)
.font(.callout)
Picker("mode", selection: $mode ) {
Picker("Mode", selection: $mode ) {
ForEach(SerialModeTypes.allCases) { smt in
Text(smt.description)
}
@ -76,7 +76,7 @@ struct SerialConfig: View {
Picker("Receive data (rxd) GPIO pin", selection: $rxd) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}
@ -88,7 +88,7 @@ struct SerialConfig: View {
Picker("Transmit data (txd) GPIO pin", selection: $txd) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}

View file

@ -50,7 +50,7 @@ struct StoreForwardConfig: View {
Text("Send a heartbeat to advertise the server's presence.")
}
Picker("Number of records", selection: $records) {
Text("unset").tag(0)
Text("Unset").tag(0)
Text("25").tag(25)
Text("50").tag(50)
Text("75").tag(75)
@ -58,7 +58,7 @@ struct StoreForwardConfig: View {
}
.pickerStyle(DefaultPickerStyle())
Picker("History Return Max", selection: $historyReturnMax) {
Text("unset").tag(0)
Text("Unset").tag(0)
Text("25").tag(25)
Text("50").tag(50)
Text("75").tag(75)
@ -66,7 +66,7 @@ struct StoreForwardConfig: View {
}
.pickerStyle(DefaultPickerStyle())
Picker("History Return Window", selection: $historyReturnWindow) {
Text("unset").tag(0)
Text("Unset").tag(0)
Text("One Minute").tag(60)
Text("Five Minutes").tag(300)
Text("Ten Minutes").tag(600)

View file

@ -46,7 +46,7 @@ struct TelemetryConfig: View {
.foregroundColor(.gray)
.font(.callout)
.listRowSeparator(.visible)
Picker("Sensor Metrics", selection: $environmentUpdateInterval ) {
Picker("Environment Metrics", selection: $environmentUpdateInterval ) {
ForEach(UpdateIntervals.allCases) { ui in
if ui.rawValue >= 900 {
Text(ui.description)
@ -55,7 +55,7 @@ struct TelemetryConfig: View {
}
.pickerStyle(DefaultPickerStyle())
.listRowSeparator(.hidden)
Text("How often sensor metrics are sent out over the mesh. Default is 30 minutes.")
Text("How often environment metrics are sent out over the mesh. Default is 30 minutes.")
.foregroundColor(.gray)
.font(.callout)
}

View file

@ -60,8 +60,8 @@ struct NetworkConfig: View {
}
.keyboardType(.default)
HStack {
Label("password", systemImage: "wallet.pass")
TextField("password", text: $wifiPsk)
Label("Password", systemImage: "wallet.pass")
TextField("Password", text: $wifiPsk)
.foregroundColor(.gray)
.autocapitalization(.none)
.disableAutocorrection(true)

View file

@ -114,7 +114,7 @@ struct PositionConfig: View {
Picker("Minimum Distance", selection: $broadcastSmartMinimumDistance) {
ForEach(10..<151) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
if $0.isMultiple(of: 5) {
Text("\($0)")
@ -139,7 +139,6 @@ struct PositionConfig: View {
ForEach(GpsMode.allCases, id: \.self) { at in
Text(at.description)
.tag(at.id)
}
}
.pickerStyle(SegmentedPickerStyle())
@ -210,7 +209,7 @@ struct PositionConfig: View {
}
Toggle(isOn: $includeTimestamp) { // 128
Label("timestamp", systemImage: "clock")
Label("Timestamp", systemImage: "clock")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
.onChange(of: includeTimestamp) { _, newIncludeTimestamp in
@ -283,7 +282,7 @@ struct PositionConfig: View {
Picker("GPS Receive GPIO", selection: $rxGpio) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}
@ -293,7 +292,7 @@ struct PositionConfig: View {
Picker("GPS Transmit GPIO", selection: $txGpio) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}
@ -303,7 +302,7 @@ struct PositionConfig: View {
Picker("GPS EN GPIO", selection: $gpsEnGpio) {
ForEach(0..<49) {
if $0 == 0 {
Text("unset")
Text("Unset")
} else {
Text("Pin \($0)")
}
@ -314,7 +313,6 @@ struct PositionConfig: View {
.font(.caption)
}
}
var saveButton: some View {
SaveConfigButton(node: node, hasChanges: $hasChanges) {
if fixedPosition && !supportedVersion {
@ -399,11 +397,7 @@ struct PositionConfig: View {
.navigationTitle("position.config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(
bluetoothOn: bleManager.isSwitchedOn,
deviceConnected: bleManager.connectedPeripheral != nil,
name: bleManager.connectedPeripheral?.shortName ?? "?"
)
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: bleManager.connectedPeripheral?.shortName ?? "?")
}
)
.onFirstAppear {

View file

@ -42,7 +42,7 @@ struct PowerConfig: View {
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
if shutdownOnPowerLoss {
Picker("config.power.shutdown.after.secs", selection: $shutdownAfterSecs) {
Picker("After", selection: $shutdownAfterSecs) {
ForEach(PowerIntervals.allCases) { at in
Text(at.description)
}
@ -50,7 +50,7 @@ struct PowerConfig: View {
.pickerStyle(DefaultPickerStyle())
}
} header: {
Text("config.power.settings")
Text("Power")
}
if currentDevice?.architecture == .esp32 || currentDevice?.architecture == .esp32S3 {
Section {

View file

@ -24,7 +24,7 @@ struct SaveConfigButton: View {
isPresented: $isPresentingSaveConfirm,
titleVisibility: .visible
) {
let nodeName = node?.user?.longName ?? "unknown".localized
let nodeName = node?.user?.longName ?? "Unknown".localized
let buttonText = String.localizedStringWithFormat("save.config %@".localized, nodeName)
Button(buttonText) {
onConfirmation()

View file

@ -77,7 +77,7 @@ struct Firmware: View {
Text("Get the latest stable firmware")
.fixedSize(horizontal: false, vertical: true)
.font(.callout)
Link("\(latestStable?.title ?? "unknown".localized)", destination: URL(string: "\(latestStable?.zipURL ?? "https://meshtastic.org")")!)
Link("\(latestStable?.title ?? "Unknown".localized)", destination: URL(string: "\(latestStable?.zipURL ?? "https://meshtastic.org")")!)
.font(.caption)
Link("Release Notes", destination: URL(string: "\(latestStable?.pageURL ?? "https://meshtastic.org")")!)
.font(.caption)
@ -86,7 +86,7 @@ struct Firmware: View {
Text("Get the latest alpha firmware")
.fixedSize(horizontal: false, vertical: true)
.font(.callout)
Link("\(latestAlpha?.title ?? "unknown".localized)", destination: URL(string: "\(latestAlpha?.zipURL ?? "https://meshtastic.org")")!)
Link("\(latestAlpha?.title ?? "Unknown".localized)", destination: URL(string: "\(latestAlpha?.zipURL ?? "https://meshtastic.org")")!)
.font(.caption)
Link("Release Notes", destination: URL(string: "\(latestAlpha?.pageURL ?? "https://meshtastic.org")")!)
.font(.caption)

View file

@ -136,7 +136,7 @@ struct AppLogFilter: View {
Button {
dismiss()
} label: {
Label("close", systemImage: "xmark")
Label("Close", systemImage: "xmark")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)

View file

@ -124,7 +124,7 @@ struct LogDetail: View {
/// message
Label {
Text("log.message".localized + ":")
Text("Message".localized + ":")
.font(idiom == .phone ? .caption : .title)
.frame(width: idiom == .phone ? 115 : 190, alignment: .trailing)
Text(log.composedMessage)
@ -151,7 +151,7 @@ struct LogDetail: View {
Button {
dismiss()
} label: {
Label("close", systemImage: "xmark")
Label("Close", systemImage: "xmark")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)

View file

@ -250,7 +250,7 @@ struct RouteRecorder: View {
}
isShowingDetails = false
} label: {
Label("finish", systemImage: "flag.checkered")
Label("Finish", systemImage: "flag.checkered")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)
@ -261,7 +261,7 @@ struct RouteRecorder: View {
Button(role: .cancel) {
isShowingDetails = false
} label: {
Label("close", systemImage: "xmark")
Label("Close", systemImage: "xmark")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)

View file

@ -200,7 +200,7 @@ struct Routes: View {
.foregroundColor(Color.gray)
}
.onAppear {
name = selectedRoute?.name ?? "unknown".localized
name = selectedRoute?.name ?? "Unknown".localized
notes = selectedRoute?.notes ?? ""
enabled = selectedRoute?.enabled ?? false
color = Color(UIColor(hex: UInt32(selectedRoute?.color ?? 0)))

View file

@ -78,7 +78,7 @@ struct Settings: View {
NavigationLink(value: SettingsNavigationState.channels) {
Label {
Text("channels")
Text("Channels")
} icon: {
Image(systemName: "fibrechannel")
}
@ -108,7 +108,7 @@ struct Settings: View {
Section("device.configuration") {
NavigationLink(value: SettingsNavigationState.user) {
Label {
Text("user")
Text("User")
} icon: {
Image(systemName: "person.crop.rectangle.fill")
}
@ -148,7 +148,7 @@ struct Settings: View {
NavigationLink(value: SettingsNavigationState.position) {
Label {
Text("position")
Text("Position")
} icon: {
Image(systemName: "location")
}
@ -156,7 +156,7 @@ struct Settings: View {
NavigationLink(value: SettingsNavigationState.power) {
Label {
Text("config.power.settings")
Text("Power")
} icon: {
Image(systemName: "bolt.fill")
}
@ -209,7 +209,7 @@ struct Settings: View {
if isModuleSupported(.mqttConfig) {
NavigationLink(value: SettingsNavigationState.mqtt) {
Label {
Text("mqtt")
Text("MQTT")
} icon: {
Image(systemName: "dot.radiowaves.up.forward")
}
@ -229,7 +229,7 @@ struct Settings: View {
if isModuleSupported(.paxcounterConfig) {
NavigationLink(value: SettingsNavigationState.paxCounter) {
Label {
Text("config.module.paxcounter.settings")
Text("PAX Counter")
} icon: {
Image(systemName: "figure.walk.motion")
}
@ -239,7 +239,7 @@ struct Settings: View {
if isModuleSupported(.audioConfig) {
NavigationLink(value: SettingsNavigationState.ringtone) {
Label {
Text("ringtone")
Text("Ringtone")
} icon: {
Image(systemName: "music.note.list")
}
@ -249,7 +249,7 @@ struct Settings: View {
if isModuleSupported(.serialConfig) {
NavigationLink(value: SettingsNavigationState.serial) {
Label {
Text("serial")
Text("Serial")
} icon: {
Image(systemName: "terminal")
}
@ -388,14 +388,14 @@ struct Settings: View {
/// Connected Node
if node.num == bleManager.connectedPeripheral?.num ?? 0 {
Label {
Text("BLE: \(node.user?.longName?.addingVariationSelectors ?? "unknown".localized)")
Text("BLE: \(node.user?.longName?.addingVariationSelectors ?? "Unknown".localized)")
} icon: {
Image(systemName: "antenna.radiowaves.left.and.right")
}
.tag(Int(node.num))
} else if node.canRemoteAdmin && UserDefaults.enableAdministration && node.sessionPasskey != nil { /// Nodes using the new PKI system
Label {
Text("Remote PKI Admin: \(node.user?.longName ?? "unknown".localized)")
Text("Remote PKI Admin: \(node.user?.longName ?? "Unknown".localized)")
} icon: {
Image(systemName: "av.remote")
}
@ -403,21 +403,21 @@ struct Settings: View {
.tag(Int(node.num))
} else if !UserDefaults.enableAdministration && node.metadata != nil { /// Nodes using the old admin system
Label {
Text("Remote Legacy Admin: \(node.user?.longName ?? "unknown".localized)")
Text("Remote Legacy Admin: \(node.user?.longName ?? "Unknown".localized)")
} icon: {
Image(systemName: "av.remote")
}
.tag(Int(node.num))
} else if UserDefaults.enableAdministration && node.user?.pkiEncrypted ?? false {
Label {
Text("Request PKI Admin: \(node.user?.longName?.addingVariationSelectors ?? "unknown".localized)")
Text("Request PKI Admin: \(node.user?.longName?.addingVariationSelectors ?? "Unknown".localized)")
} icon: {
Image(systemName: "rectangle.and.hand.point.up.left")
}
.tag(Int(node.num))
} else if !UserDefaults.enableAdministration {
Label {
Text("Request Legacy Admin: \(node.user?.longName?.addingVariationSelectors ?? "unknown".localized)")
Text("Request Legacy Admin: \(node.user?.longName?.addingVariationSelectors ?? "Unknown".localized)")
} icon: {
Image(systemName: "rectangle.and.hand.point.up.left")
}
@ -442,7 +442,7 @@ struct Settings: View {
TipView(AdminChannelTip(), arrowEdge: .top)
} else {
if bleManager.connectedPeripheral != nil {
Text("Connected Node \(node?.user?.longName?.addingVariationSelectors ?? "unknown".localized)")
Text("Connected Node \(node?.user?.longName?.addingVariationSelectors ?? "Unknown".localized)")
}
}
}
@ -542,7 +542,7 @@ struct Settings: View {
}
}
}
.navigationTitle("settings")
.navigationTitle("Settings")
.navigationBarItems(
leading: MeshtasticLogo().onLongPressGesture(minimumDuration: 1.0) {
self.moduleOverride.toggle()

View file

@ -62,7 +62,7 @@ struct ShareChannels: View {
Grid {
GridRow {
Spacer()
Text("include")
Text("Include")
.font(.caption)
.fontWeight(.bold)
.padding(.trailing)
@ -70,7 +70,7 @@ struct ShareChannels: View {
.font(.caption)
.fontWeight(.bold)
.padding(.trailing)
Text("encrypted")
Text("Encrypted")
.font(.caption)
.fontWeight(.bold)
}

View file

@ -1,6 +1,5 @@
// DO NOT EDIT.
// swift-format-ignore-file
// swiftlint:disable all
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: meshtastic/admin.proto
@ -25,7 +24,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
/// This message is handled by the Admin module and is responsible for all settings/channel read/write operations.
/// This message is used to do settings operations to both remote AND local nodes.
/// (Prior to 1.2 these operations were done via special ToRadio operations)
public struct AdminMessage: @unchecked Sendable {
public struct AdminMessage {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -564,7 +563,7 @@ public struct AdminMessage: @unchecked Sendable {
///
/// TODO: REPLACE
public enum OneOf_PayloadVariant: Equatable, Sendable {
public enum OneOf_PayloadVariant: Equatable {
///
/// Send the specified channel in the response to this message
/// NOTE: This field is sent with the channel index + 1 (to ensure we never try to send 'zero' - which protobufs treats as not present)
@ -729,11 +728,225 @@ public struct AdminMessage: @unchecked Sendable {
/// Tell the node to reset the nodedb.
case nodedbReset(Int32)
#if !swift(>=4.1)
public static func ==(lhs: AdminMessage.OneOf_PayloadVariant, rhs: AdminMessage.OneOf_PayloadVariant) -> Bool {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch (lhs, rhs) {
case (.getChannelRequest, .getChannelRequest): return {
guard case .getChannelRequest(let l) = lhs, case .getChannelRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getChannelResponse, .getChannelResponse): return {
guard case .getChannelResponse(let l) = lhs, case .getChannelResponse(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getOwnerRequest, .getOwnerRequest): return {
guard case .getOwnerRequest(let l) = lhs, case .getOwnerRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getOwnerResponse, .getOwnerResponse): return {
guard case .getOwnerResponse(let l) = lhs, case .getOwnerResponse(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getConfigRequest, .getConfigRequest): return {
guard case .getConfigRequest(let l) = lhs, case .getConfigRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getConfigResponse, .getConfigResponse): return {
guard case .getConfigResponse(let l) = lhs, case .getConfigResponse(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getModuleConfigRequest, .getModuleConfigRequest): return {
guard case .getModuleConfigRequest(let l) = lhs, case .getModuleConfigRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getModuleConfigResponse, .getModuleConfigResponse): return {
guard case .getModuleConfigResponse(let l) = lhs, case .getModuleConfigResponse(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getCannedMessageModuleMessagesRequest, .getCannedMessageModuleMessagesRequest): return {
guard case .getCannedMessageModuleMessagesRequest(let l) = lhs, case .getCannedMessageModuleMessagesRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getCannedMessageModuleMessagesResponse, .getCannedMessageModuleMessagesResponse): return {
guard case .getCannedMessageModuleMessagesResponse(let l) = lhs, case .getCannedMessageModuleMessagesResponse(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getDeviceMetadataRequest, .getDeviceMetadataRequest): return {
guard case .getDeviceMetadataRequest(let l) = lhs, case .getDeviceMetadataRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getDeviceMetadataResponse, .getDeviceMetadataResponse): return {
guard case .getDeviceMetadataResponse(let l) = lhs, case .getDeviceMetadataResponse(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getRingtoneRequest, .getRingtoneRequest): return {
guard case .getRingtoneRequest(let l) = lhs, case .getRingtoneRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getRingtoneResponse, .getRingtoneResponse): return {
guard case .getRingtoneResponse(let l) = lhs, case .getRingtoneResponse(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getDeviceConnectionStatusRequest, .getDeviceConnectionStatusRequest): return {
guard case .getDeviceConnectionStatusRequest(let l) = lhs, case .getDeviceConnectionStatusRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getDeviceConnectionStatusResponse, .getDeviceConnectionStatusResponse): return {
guard case .getDeviceConnectionStatusResponse(let l) = lhs, case .getDeviceConnectionStatusResponse(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.setHamMode, .setHamMode): return {
guard case .setHamMode(let l) = lhs, case .setHamMode(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getNodeRemoteHardwarePinsRequest, .getNodeRemoteHardwarePinsRequest): return {
guard case .getNodeRemoteHardwarePinsRequest(let l) = lhs, case .getNodeRemoteHardwarePinsRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getNodeRemoteHardwarePinsResponse, .getNodeRemoteHardwarePinsResponse): return {
guard case .getNodeRemoteHardwarePinsResponse(let l) = lhs, case .getNodeRemoteHardwarePinsResponse(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.enterDfuModeRequest, .enterDfuModeRequest): return {
guard case .enterDfuModeRequest(let l) = lhs, case .enterDfuModeRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.deleteFileRequest, .deleteFileRequest): return {
guard case .deleteFileRequest(let l) = lhs, case .deleteFileRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.setScale, .setScale): return {
guard case .setScale(let l) = lhs, case .setScale(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.backupPreferences, .backupPreferences): return {
guard case .backupPreferences(let l) = lhs, case .backupPreferences(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.restorePreferences, .restorePreferences): return {
guard case .restorePreferences(let l) = lhs, case .restorePreferences(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.removeBackupPreferences, .removeBackupPreferences): return {
guard case .removeBackupPreferences(let l) = lhs, case .removeBackupPreferences(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.setOwner, .setOwner): return {
guard case .setOwner(let l) = lhs, case .setOwner(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.setChannel, .setChannel): return {
guard case .setChannel(let l) = lhs, case .setChannel(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.setConfig, .setConfig): return {
guard case .setConfig(let l) = lhs, case .setConfig(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.setModuleConfig, .setModuleConfig): return {
guard case .setModuleConfig(let l) = lhs, case .setModuleConfig(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.setCannedMessageModuleMessages, .setCannedMessageModuleMessages): return {
guard case .setCannedMessageModuleMessages(let l) = lhs, case .setCannedMessageModuleMessages(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.setRingtoneMessage, .setRingtoneMessage): return {
guard case .setRingtoneMessage(let l) = lhs, case .setRingtoneMessage(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.removeByNodenum, .removeByNodenum): return {
guard case .removeByNodenum(let l) = lhs, case .removeByNodenum(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.setFavoriteNode, .setFavoriteNode): return {
guard case .setFavoriteNode(let l) = lhs, case .setFavoriteNode(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.removeFavoriteNode, .removeFavoriteNode): return {
guard case .removeFavoriteNode(let l) = lhs, case .removeFavoriteNode(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.setFixedPosition, .setFixedPosition): return {
guard case .setFixedPosition(let l) = lhs, case .setFixedPosition(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.removeFixedPosition, .removeFixedPosition): return {
guard case .removeFixedPosition(let l) = lhs, case .removeFixedPosition(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.setTimeOnly, .setTimeOnly): return {
guard case .setTimeOnly(let l) = lhs, case .setTimeOnly(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getUiConfigRequest, .getUiConfigRequest): return {
guard case .getUiConfigRequest(let l) = lhs, case .getUiConfigRequest(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.getUiConfigResponse, .getUiConfigResponse): return {
guard case .getUiConfigResponse(let l) = lhs, case .getUiConfigResponse(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.storeUiConfig, .storeUiConfig): return {
guard case .storeUiConfig(let l) = lhs, case .storeUiConfig(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.setIgnoredNode, .setIgnoredNode): return {
guard case .setIgnoredNode(let l) = lhs, case .setIgnoredNode(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.removeIgnoredNode, .removeIgnoredNode): return {
guard case .removeIgnoredNode(let l) = lhs, case .removeIgnoredNode(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.beginEditSettings, .beginEditSettings): return {
guard case .beginEditSettings(let l) = lhs, case .beginEditSettings(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.commitEditSettings, .commitEditSettings): return {
guard case .commitEditSettings(let l) = lhs, case .commitEditSettings(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.factoryResetDevice, .factoryResetDevice): return {
guard case .factoryResetDevice(let l) = lhs, case .factoryResetDevice(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.rebootOtaSeconds, .rebootOtaSeconds): return {
guard case .rebootOtaSeconds(let l) = lhs, case .rebootOtaSeconds(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.exitSimulator, .exitSimulator): return {
guard case .exitSimulator(let l) = lhs, case .exitSimulator(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.rebootSeconds, .rebootSeconds): return {
guard case .rebootSeconds(let l) = lhs, case .rebootSeconds(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.shutdownSeconds, .shutdownSeconds): return {
guard case .shutdownSeconds(let l) = lhs, case .shutdownSeconds(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.factoryResetConfig, .factoryResetConfig): return {
guard case .factoryResetConfig(let l) = lhs, case .factoryResetConfig(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.nodedbReset, .nodedbReset): return {
guard case .nodedbReset(let l) = lhs, case .nodedbReset(let r) = rhs else { preconditionFailure() }
return l == r
}()
default: return false
}
}
#endif
}
///
/// TODO: REPLACE
public enum ConfigType: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum ConfigType: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -813,25 +1026,11 @@ public struct AdminMessage: @unchecked Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [AdminMessage.ConfigType] = [
.deviceConfig,
.positionConfig,
.powerConfig,
.networkConfig,
.displayConfig,
.loraConfig,
.bluetoothConfig,
.securityConfig,
.sessionkeyConfig,
.deviceuiConfig,
]
}
///
/// TODO: REPLACE
public enum ModuleConfigType: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum ModuleConfigType: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -929,26 +1128,9 @@ public struct AdminMessage: @unchecked Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [AdminMessage.ModuleConfigType] = [
.mqttConfig,
.serialConfig,
.extnotifConfig,
.storeforwardConfig,
.rangetestConfig,
.telemetryConfig,
.cannedmsgConfig,
.audioConfig,
.remotehardwareConfig,
.neighborinfoConfig,
.ambientlightingConfig,
.detectionsensorConfig,
.paxcounterConfig,
]
}
public enum BackupLocation: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum BackupLocation: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -980,20 +1162,61 @@ public struct AdminMessage: @unchecked Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [AdminMessage.BackupLocation] = [
.flash,
.sd,
]
}
public init() {}
}
#if swift(>=4.2)
extension AdminMessage.ConfigType: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [AdminMessage.ConfigType] = [
.deviceConfig,
.positionConfig,
.powerConfig,
.networkConfig,
.displayConfig,
.loraConfig,
.bluetoothConfig,
.securityConfig,
.sessionkeyConfig,
.deviceuiConfig,
]
}
extension AdminMessage.ModuleConfigType: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [AdminMessage.ModuleConfigType] = [
.mqttConfig,
.serialConfig,
.extnotifConfig,
.storeforwardConfig,
.rangetestConfig,
.telemetryConfig,
.cannedmsgConfig,
.audioConfig,
.remotehardwareConfig,
.neighborinfoConfig,
.ambientlightingConfig,
.detectionsensorConfig,
.paxcounterConfig,
]
}
extension AdminMessage.BackupLocation: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [AdminMessage.BackupLocation] = [
.flash,
.sd,
]
}
#endif // swift(>=4.2)
///
/// Parameters for setting up Meshtastic for ameteur radio usage
public struct HamParameters: Sendable {
public struct HamParameters {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -1023,7 +1246,7 @@ public struct HamParameters: Sendable {
///
/// Response envelope for node_remote_hardware_pins
public struct NodeRemoteHardwarePinsResponse: Sendable {
public struct NodeRemoteHardwarePinsResponse {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -1037,6 +1260,16 @@ public struct NodeRemoteHardwarePinsResponse: Sendable {
public init() {}
}
#if swift(>=5.5) && canImport(_Concurrency)
extension AdminMessage: @unchecked Sendable {}
extension AdminMessage.OneOf_PayloadVariant: @unchecked Sendable {}
extension AdminMessage.ConfigType: @unchecked Sendable {}
extension AdminMessage.ModuleConfigType: @unchecked Sendable {}
extension AdminMessage.BackupLocation: @unchecked Sendable {}
extension HamParameters: @unchecked Sendable {}
extension NodeRemoteHardwarePinsResponse: @unchecked Sendable {}
#endif // swift(>=5.5) && canImport(_Concurrency)
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "meshtastic"
@ -1890,7 +2123,7 @@ extension HamParameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementa
if self.txPower != 0 {
try visitor.visitSingularInt32Field(value: self.txPower, fieldNumber: 2)
}
if self.frequency.bitPattern != 0 {
if self.frequency != 0 {
try visitor.visitSingularFloatField(value: self.frequency, fieldNumber: 3)
}
if !self.shortName.isEmpty {

View file

@ -1,6 +1,5 @@
// DO NOT EDIT.
// swift-format-ignore-file
// swiftlint:disable all
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: meshtastic/apponly.proto
@ -8,6 +7,7 @@
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
import Foundation
import SwiftProtobuf
// If the compiler emits an error on this type, it is because this file
@ -26,7 +26,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
/// any SECONDARY channels.
/// No DISABLED channels are included.
/// This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels as a (long) URL
public struct ChannelSet: Sendable {
public struct ChannelSet {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -53,6 +53,10 @@ public struct ChannelSet: Sendable {
fileprivate var _loraConfig: Config.LoRaConfig? = nil
}
#if swift(>=5.5) && canImport(_Concurrency)
extension ChannelSet: @unchecked Sendable {}
#endif // swift(>=5.5) && canImport(_Concurrency)
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "meshtastic"

View file

@ -1,6 +1,5 @@
// DO NOT EDIT.
// swift-format-ignore-file
// swiftlint:disable all
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: meshtastic/atak.proto
@ -21,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
typealias Version = _2
}
public enum Team: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum Team: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -131,6 +130,11 @@ public enum Team: SwiftProtobuf.Enum, Swift.CaseIterable {
}
}
}
#if swift(>=4.2)
extension Team: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Team] = [
.unspecifedColor,
@ -149,12 +153,13 @@ public enum Team: SwiftProtobuf.Enum, Swift.CaseIterable {
.darkGreen,
.brown,
]
}
#endif // swift(>=4.2)
///
/// Role of the group member
public enum MemberRole: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum MemberRole: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -228,6 +233,11 @@ public enum MemberRole: SwiftProtobuf.Enum, Swift.CaseIterable {
}
}
}
#if swift(>=4.2)
extension MemberRole: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [MemberRole] = [
.unspecifed,
@ -240,12 +250,13 @@ public enum MemberRole: SwiftProtobuf.Enum, Swift.CaseIterable {
.rto,
.k9,
]
}
#endif // swift(>=4.2)
///
/// Packets for the official ATAK Plugin
public struct TAKPacket: @unchecked Sendable {
public struct TAKPacket {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -326,7 +337,7 @@ public struct TAKPacket: @unchecked Sendable {
///
/// The payload of the packet
public enum OneOf_PayloadVariant: Equatable, @unchecked Sendable {
public enum OneOf_PayloadVariant: Equatable {
///
/// TAK position report
case pli(PLI)
@ -338,6 +349,28 @@ public struct TAKPacket: @unchecked Sendable {
/// May be compressed / truncated by the sender (EUD)
case detail(Data)
#if !swift(>=4.1)
public static func ==(lhs: TAKPacket.OneOf_PayloadVariant, rhs: TAKPacket.OneOf_PayloadVariant) -> Bool {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch (lhs, rhs) {
case (.pli, .pli): return {
guard case .pli(let l) = lhs, case .pli(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.chat, .chat): return {
guard case .chat(let l) = lhs, case .chat(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.detail, .detail): return {
guard case .detail(let l) = lhs, case .detail(let r) = rhs else { preconditionFailure() }
return l == r
}()
default: return false
}
}
#endif
}
public init() {}
@ -349,7 +382,7 @@ public struct TAKPacket: @unchecked Sendable {
///
/// ATAK GeoChat message
public struct GeoChat: Sendable {
public struct GeoChat {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -391,7 +424,7 @@ public struct GeoChat: Sendable {
///
/// ATAK Group
/// <__group role='Team Member' name='Cyan'/>
public struct Group: Sendable {
public struct Group {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -413,7 +446,7 @@ public struct Group: Sendable {
///
/// ATAK EUD Status
/// <status battery='100' />
public struct Status: Sendable {
public struct Status {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -430,7 +463,7 @@ public struct Status: Sendable {
///
/// ATAK Contact
/// <contact endpoint='0.0.0.0:4242:tcp' phone='+12345678' callsign='FALKE'/>
public struct Contact: Sendable {
public struct Contact {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -450,7 +483,7 @@ public struct Contact: Sendable {
///
/// Position Location Information from ATAK
public struct PLI: Sendable {
public struct PLI {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -482,6 +515,18 @@ public struct PLI: Sendable {
public init() {}
}
#if swift(>=5.5) && canImport(_Concurrency)
extension Team: @unchecked Sendable {}
extension MemberRole: @unchecked Sendable {}
extension TAKPacket: @unchecked Sendable {}
extension TAKPacket.OneOf_PayloadVariant: @unchecked Sendable {}
extension GeoChat: @unchecked Sendable {}
extension Group: @unchecked Sendable {}
extension Status: @unchecked Sendable {}
extension Contact: @unchecked Sendable {}
extension PLI: @unchecked Sendable {}
#endif // swift(>=5.5) && canImport(_Concurrency)
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "meshtastic"

View file

@ -1,6 +1,5 @@
// DO NOT EDIT.
// swift-format-ignore-file
// swiftlint:disable all
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: meshtastic/cannedmessages.proto
@ -8,6 +7,7 @@
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
import Foundation
import SwiftProtobuf
// If the compiler emits an error on this type, it is because this file
@ -22,7 +22,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
///
/// Canned message module configuration.
public struct CannedMessageModuleConfig: Sendable {
public struct CannedMessageModuleConfig {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -36,6 +36,10 @@ public struct CannedMessageModuleConfig: Sendable {
public init() {}
}
#if swift(>=5.5) && canImport(_Concurrency)
extension CannedMessageModuleConfig: @unchecked Sendable {}
#endif // swift(>=5.5) && canImport(_Concurrency)
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "meshtastic"

View file

@ -1,6 +1,5 @@
// DO NOT EDIT.
// swift-format-ignore-file
// swiftlint:disable all
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: meshtastic/channel.proto
@ -37,15 +36,13 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
/// FIXME: Add description of multi-channel support and how primary vs secondary channels are used.
/// FIXME: explain how apps use channels for security.
/// explain how remote settings and remote gpio are managed as an example
public struct ChannelSettings: @unchecked Sendable {
public struct ChannelSettings {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
///
/// Deprecated in favor of LoraConfig.channel_num
///
/// NOTE: This field was marked as deprecated in the .proto file.
public var channelNum: UInt32 = 0
///
@ -114,7 +111,7 @@ public struct ChannelSettings: @unchecked Sendable {
///
/// This message is specifically for modules to store per-channel configuration data.
public struct ModuleSettings: Sendable {
public struct ModuleSettings {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -135,7 +132,7 @@ public struct ModuleSettings: Sendable {
///
/// A pair of a channel number, mode and the (sharable) settings for that channel
public struct Channel: Sendable {
public struct Channel {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -173,7 +170,7 @@ public struct Channel: Sendable {
/// cross band routing as needed.
/// If a device has only a single radio (the common case) only one channel can be PRIMARY at a time
/// (but any number of SECONDARY channels can't be sent received on that common frequency)
public enum Role: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum Role: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -212,13 +209,6 @@ public struct Channel: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Channel.Role] = [
.disabled,
.primary,
.secondary,
]
}
public init() {}
@ -226,6 +216,26 @@ public struct Channel: Sendable {
fileprivate var _settings: ChannelSettings? = nil
}
#if swift(>=4.2)
extension Channel.Role: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Channel.Role] = [
.disabled,
.primary,
.secondary,
]
}
#endif // swift(>=4.2)
#if swift(>=5.5) && canImport(_Concurrency)
extension ChannelSettings: @unchecked Sendable {}
extension ModuleSettings: @unchecked Sendable {}
extension Channel: @unchecked Sendable {}
extension Channel.Role: @unchecked Sendable {}
#endif // swift(>=5.5) && canImport(_Concurrency)
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "meshtastic"

View file

@ -1,6 +1,5 @@
// DO NOT EDIT.
// swift-format-ignore-file
// swiftlint:disable all
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: meshtastic/clientonly.proto
@ -8,6 +7,7 @@
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
import Foundation
import SwiftProtobuf
// If the compiler emits an error on this type, it is because this file
@ -23,7 +23,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
///
/// This abstraction is used to contain any configuration for provisioning a node on any client.
/// It is useful for importing and exporting configurations.
public struct DeviceProfile: Sendable {
public struct DeviceProfile {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -130,6 +130,10 @@ public struct DeviceProfile: Sendable {
fileprivate var _cannedMessages: String? = nil
}
#if swift(>=5.5) && canImport(_Concurrency)
extension DeviceProfile: @unchecked Sendable {}
#endif // swift(>=5.5) && canImport(_Concurrency)
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "meshtastic"

View file

@ -1,6 +1,5 @@
// DO NOT EDIT.
// swift-format-ignore-file
// swiftlint:disable all
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: meshtastic/config.proto
@ -21,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
typealias Version = _2
}
public struct Config: Sendable {
public struct Config {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -114,7 +113,7 @@ public struct Config: Sendable {
///
/// Payload Variant
public enum OneOf_PayloadVariant: Equatable, Sendable {
public enum OneOf_PayloadVariant: Equatable {
case device(Config.DeviceConfig)
case position(Config.PositionConfig)
case power(Config.PowerConfig)
@ -126,11 +125,61 @@ public struct Config: Sendable {
case sessionkey(Config.SessionkeyConfig)
case deviceUi(DeviceUIConfig)
#if !swift(>=4.1)
public static func ==(lhs: Config.OneOf_PayloadVariant, rhs: Config.OneOf_PayloadVariant) -> Bool {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch (lhs, rhs) {
case (.device, .device): return {
guard case .device(let l) = lhs, case .device(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.position, .position): return {
guard case .position(let l) = lhs, case .position(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.power, .power): return {
guard case .power(let l) = lhs, case .power(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.network, .network): return {
guard case .network(let l) = lhs, case .network(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.display, .display): return {
guard case .display(let l) = lhs, case .display(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.lora, .lora): return {
guard case .lora(let l) = lhs, case .lora(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.bluetooth, .bluetooth): return {
guard case .bluetooth(let l) = lhs, case .bluetooth(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.security, .security): return {
guard case .security(let l) = lhs, case .security(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.sessionkey, .sessionkey): return {
guard case .sessionkey(let l) = lhs, case .sessionkey(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.deviceUi, .deviceUi): return {
guard case .deviceUi(let l) = lhs, case .deviceUi(let r) = rhs else { preconditionFailure() }
return l == r
}()
default: return false
}
}
#endif
}
///
/// Configuration
public struct DeviceConfig: Sendable {
public struct DeviceConfig {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -142,8 +191,6 @@ public struct Config: Sendable {
///
/// Disabling this will disable the SerialConsole by not initilizing the StreamAPI
/// Moved to SecurityConfig
///
/// NOTE: This field was marked as deprecated in the .proto file.
public var serialEnabled: Bool = false
///
@ -173,8 +220,6 @@ public struct Config: Sendable {
/// If true, device is considered to be "managed" by a mesh administrator
/// Clients should then limit available configuration and administrative options inside the user interface
/// Moved to SecurityConfig
///
/// NOTE: This field was marked as deprecated in the .proto file.
public var isManaged: Bool = false
///
@ -193,7 +238,7 @@ public struct Config: Sendable {
///
/// Defines the device's role on the Mesh network
public enum Role: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum Role: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -211,8 +256,6 @@ public struct Config: Sendable {
/// The wifi radio and the oled screen will be put to sleep.
/// This mode may still potentially have higher power usage due to it's preference in message rebroadcasting on the mesh.
case router // = 2
/// NOTE: This enum value was marked as deprecated in the .proto file
case routerClient // = 3
///
@ -313,27 +356,11 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DeviceConfig.Role] = [
.client,
.clientMute,
.router,
.routerClient,
.repeater,
.tracker,
.sensor,
.tak,
.clientHidden,
.lostAndFound,
.takTracker,
.routerLate,
]
}
///
/// Defines the device's behavior for how messages are rebroadcast
public enum RebroadcastMode: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum RebroadcastMode: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -394,16 +421,6 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DeviceConfig.RebroadcastMode] = [
.all,
.allSkipDecoding,
.localOnly,
.knownOnly,
.none,
.corePortnumsOnly,
]
}
public init() {}
@ -411,7 +428,7 @@ public struct Config: Sendable {
///
/// Position Config
public struct PositionConfig: Sendable {
public struct PositionConfig {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -433,8 +450,6 @@ public struct Config: Sendable {
///
/// Is GPS enabled for this node?
///
/// NOTE: This field was marked as deprecated in the .proto file.
public var gpsEnabled: Bool = false
///
@ -445,8 +460,6 @@ public struct Config: Sendable {
///
/// Deprecated in favor of using smart / regular broadcast intervals as implicit attempt time
///
/// NOTE: This field was marked as deprecated in the .proto file.
public var gpsAttemptTime: UInt32 = 0
///
@ -487,7 +500,7 @@ public struct Config: Sendable {
/// are always included (also time if GPS-synced)
/// NOTE: the more fields are included, the larger the message will be -
/// leading to longer airtime and a higher risk of packet loss
public enum PositionFlags: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum PositionFlags: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -577,24 +590,9 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.PositionConfig.PositionFlags] = [
.unset,
.altitude,
.altitudeMsl,
.geoidalSeparation,
.dop,
.hvdop,
.satinview,
.seqNo,
.timestamp,
.heading,
.speed,
]
}
public enum GpsMode: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum GpsMode: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -632,13 +630,6 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.PositionConfig.GpsMode] = [
.disabled,
.enabled,
.notPresent,
]
}
public init() {}
@ -647,7 +638,7 @@ public struct Config: Sendable {
///
/// Power Config\
/// See [Power Config](/docs/settings/config/power) for additional power config details.
public struct PowerConfig: Sendable {
public struct PowerConfig {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -707,7 +698,7 @@ public struct Config: Sendable {
///
/// Network Config
public struct NetworkConfig: Sendable {
public struct NetworkConfig {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -758,7 +749,7 @@ public struct Config: Sendable {
public var unknownFields = SwiftProtobuf.UnknownStorage()
public enum AddressMode: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum AddressMode: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -790,17 +781,11 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.NetworkConfig.AddressMode] = [
.dhcp,
.static,
]
}
///
/// Available flags auxiliary network protocols
public enum ProtocolFlags: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum ProtocolFlags: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -832,15 +817,9 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.NetworkConfig.ProtocolFlags] = [
.noBroadcast,
.udpBroadcast,
]
}
public struct IpV4Config: Sendable {
public struct IpV4Config {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -873,7 +852,7 @@ public struct Config: Sendable {
///
/// Display Config
public struct DisplayConfig: Sendable {
public struct DisplayConfig {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -934,7 +913,7 @@ public struct Config: Sendable {
///
/// How the GPS coordinates are displayed on the OLED screen.
public enum GpsCoordinateFormat: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum GpsCoordinateFormat: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -997,21 +976,11 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DisplayConfig.GpsCoordinateFormat] = [
.dec,
.dms,
.utm,
.mgrs,
.olc,
.osgr,
]
}
///
/// Unit display preference
public enum DisplayUnits: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum DisplayUnits: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -1043,34 +1012,32 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DisplayConfig.DisplayUnits] = [
.metric,
.imperial,
]
}
///
/// Override OLED outo detect with this if it fails.
public enum OledType: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum OledType: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
/// Default / Auto
/// Default / Autodetect
case oledAuto // = 0
///
/// Default / Auto
/// Default / Autodetect
case oledSsd1306 // = 1
///
/// Default / Auto
/// Default / Autodetect
case oledSh1106 // = 2
///
/// Can not be auto detected but set by proto. Used for 128x128 screens
case oledSh1107 // = 3
///
/// Can not be auto detected but set by proto. Used for 128x64 screens
case oledSh110712864 // = 4
case UNRECOGNIZED(Int)
public init() {
@ -1083,6 +1050,7 @@ public struct Config: Sendable {
case 1: self = .oledSsd1306
case 2: self = .oledSh1106
case 3: self = .oledSh1107
case 4: self = .oledSh110712864
default: self = .UNRECOGNIZED(rawValue)
}
}
@ -1093,21 +1061,14 @@ public struct Config: Sendable {
case .oledSsd1306: return 1
case .oledSh1106: return 2
case .oledSh1107: return 3
case .oledSh110712864: return 4
case .UNRECOGNIZED(let i): return i
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DisplayConfig.OledType] = [
.oledAuto,
.oledSsd1306,
.oledSh1106,
.oledSh1107,
]
}
public enum DisplayMode: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum DisplayMode: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -1151,17 +1112,9 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DisplayConfig.DisplayMode] = [
.default,
.twocolor,
.inverted,
.color,
]
}
public enum CompassOrientation: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum CompassOrientation: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -1229,18 +1182,6 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DisplayConfig.CompassOrientation] = [
.degrees0,
.degrees90,
.degrees180,
.degrees270,
.degrees0Inverted,
.degrees90Inverted,
.degrees180Inverted,
.degrees270Inverted,
]
}
public init() {}
@ -1248,7 +1189,7 @@ public struct Config: Sendable {
///
/// Lora Config
public struct LoRaConfig: @unchecked Sendable {
public struct LoRaConfig {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -1412,7 +1353,7 @@ public struct Config: Sendable {
public var unknownFields = SwiftProtobuf.UnknownStorage()
public enum RegionCode: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum RegionCode: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -1564,38 +1505,12 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.LoRaConfig.RegionCode] = [
.unset,
.us,
.eu433,
.eu868,
.cn,
.jp,
.anz,
.kr,
.tw,
.ru,
.in,
.nz865,
.th,
.lora24,
.ua433,
.ua868,
.my433,
.my919,
.sg923,
.ph433,
.ph868,
.ph915,
]
}
///
/// Standard predefined channel settings
/// Note: these mappings must match ModemPreset Choice in the device code.
public enum ModemPreset: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum ModemPreset: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -1609,8 +1524,6 @@ public struct Config: Sendable {
///
/// Very Long Range - Slow
/// Deprecated in 2.5: Works only with txco and is unusably slow
///
/// NOTE: This enum value was marked as deprecated in the .proto file
case veryLongSlow // = 2
///
@ -1674,19 +1587,6 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.LoRaConfig.ModemPreset] = [
.longFast,
.longSlow,
.veryLongSlow,
.mediumSlow,
.mediumFast,
.shortSlow,
.shortFast,
.longModerate,
.shortTurbo,
]
}
public init() {}
@ -1694,7 +1594,7 @@ public struct Config: Sendable {
fileprivate var _storage = _StorageClass.defaultInstance
}
public struct BluetoothConfig: Sendable {
public struct BluetoothConfig {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -1713,7 +1613,7 @@ public struct Config: Sendable {
public var unknownFields = SwiftProtobuf.UnknownStorage()
public enum PairingMode: SwiftProtobuf.Enum, Swift.CaseIterable {
public enum PairingMode: SwiftProtobuf.Enum {
public typealias RawValue = Int
///
@ -1751,19 +1651,12 @@ public struct Config: Sendable {
}
}
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.BluetoothConfig.PairingMode] = [
.randomPin,
.fixedPin,
.noPin,
]
}
public init() {}
}
public struct SecurityConfig: @unchecked Sendable {
public struct SecurityConfig {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -1807,7 +1700,7 @@ public struct Config: Sendable {
///
/// Blank config request, strictly for getting the session key
public struct SessionkeyConfig: Sendable {
public struct SessionkeyConfig {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -1820,6 +1713,218 @@ public struct Config: Sendable {
public init() {}
}
#if swift(>=4.2)
extension Config.DeviceConfig.Role: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DeviceConfig.Role] = [
.client,
.clientMute,
.router,
.routerClient,
.repeater,
.tracker,
.sensor,
.tak,
.clientHidden,
.lostAndFound,
.takTracker,
.routerLate,
]
}
extension Config.DeviceConfig.RebroadcastMode: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DeviceConfig.RebroadcastMode] = [
.all,
.allSkipDecoding,
.localOnly,
.knownOnly,
.none,
.corePortnumsOnly,
]
}
extension Config.PositionConfig.PositionFlags: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.PositionConfig.PositionFlags] = [
.unset,
.altitude,
.altitudeMsl,
.geoidalSeparation,
.dop,
.hvdop,
.satinview,
.seqNo,
.timestamp,
.heading,
.speed,
]
}
extension Config.PositionConfig.GpsMode: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.PositionConfig.GpsMode] = [
.disabled,
.enabled,
.notPresent,
]
}
extension Config.NetworkConfig.AddressMode: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.NetworkConfig.AddressMode] = [
.dhcp,
.static,
]
}
extension Config.NetworkConfig.ProtocolFlags: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.NetworkConfig.ProtocolFlags] = [
.noBroadcast,
.udpBroadcast,
]
}
extension Config.DisplayConfig.GpsCoordinateFormat: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DisplayConfig.GpsCoordinateFormat] = [
.dec,
.dms,
.utm,
.mgrs,
.olc,
.osgr,
]
}
extension Config.DisplayConfig.DisplayUnits: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DisplayConfig.DisplayUnits] = [
.metric,
.imperial,
]
}
extension Config.DisplayConfig.OledType: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DisplayConfig.OledType] = [
.oledAuto,
.oledSsd1306,
.oledSh1106,
.oledSh1107,
.oledSh110712864,
]
}
extension Config.DisplayConfig.DisplayMode: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DisplayConfig.DisplayMode] = [
.default,
.twocolor,
.inverted,
.color,
]
}
extension Config.DisplayConfig.CompassOrientation: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.DisplayConfig.CompassOrientation] = [
.degrees0,
.degrees90,
.degrees180,
.degrees270,
.degrees0Inverted,
.degrees90Inverted,
.degrees180Inverted,
.degrees270Inverted,
]
}
extension Config.LoRaConfig.RegionCode: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.LoRaConfig.RegionCode] = [
.unset,
.us,
.eu433,
.eu868,
.cn,
.jp,
.anz,
.kr,
.tw,
.ru,
.in,
.nz865,
.th,
.lora24,
.ua433,
.ua868,
.my433,
.my919,
.sg923,
.ph433,
.ph868,
.ph915,
]
}
extension Config.LoRaConfig.ModemPreset: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.LoRaConfig.ModemPreset] = [
.longFast,
.longSlow,
.veryLongSlow,
.mediumSlow,
.mediumFast,
.shortSlow,
.shortFast,
.longModerate,
.shortTurbo,
]
}
extension Config.BluetoothConfig.PairingMode: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static let allCases: [Config.BluetoothConfig.PairingMode] = [
.randomPin,
.fixedPin,
.noPin,
]
}
#endif // swift(>=4.2)
#if swift(>=5.5) && canImport(_Concurrency)
extension Config: @unchecked Sendable {}
extension Config.OneOf_PayloadVariant: @unchecked Sendable {}
extension Config.DeviceConfig: @unchecked Sendable {}
extension Config.DeviceConfig.Role: @unchecked Sendable {}
extension Config.DeviceConfig.RebroadcastMode: @unchecked Sendable {}
extension Config.PositionConfig: @unchecked Sendable {}
extension Config.PositionConfig.PositionFlags: @unchecked Sendable {}
extension Config.PositionConfig.GpsMode: @unchecked Sendable {}
extension Config.PowerConfig: @unchecked Sendable {}
extension Config.NetworkConfig: @unchecked Sendable {}
extension Config.NetworkConfig.AddressMode: @unchecked Sendable {}
extension Config.NetworkConfig.ProtocolFlags: @unchecked Sendable {}
extension Config.NetworkConfig.IpV4Config: @unchecked Sendable {}
extension Config.DisplayConfig: @unchecked Sendable {}
extension Config.DisplayConfig.GpsCoordinateFormat: @unchecked Sendable {}
extension Config.DisplayConfig.DisplayUnits: @unchecked Sendable {}
extension Config.DisplayConfig.OledType: @unchecked Sendable {}
extension Config.DisplayConfig.DisplayMode: @unchecked Sendable {}
extension Config.DisplayConfig.CompassOrientation: @unchecked Sendable {}
extension Config.LoRaConfig: @unchecked Sendable {}
extension Config.LoRaConfig.RegionCode: @unchecked Sendable {}
extension Config.LoRaConfig.ModemPreset: @unchecked Sendable {}
extension Config.BluetoothConfig: @unchecked Sendable {}
extension Config.BluetoothConfig.PairingMode: @unchecked Sendable {}
extension Config.SecurityConfig: @unchecked Sendable {}
extension Config.SessionkeyConfig: @unchecked Sendable {}
#endif // swift(>=5.5) && canImport(_Concurrency)
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "meshtastic"
@ -2327,7 +2432,7 @@ extension Config.PowerConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImple
if self.onBatteryShutdownAfterSecs != 0 {
try visitor.visitSingularUInt32Field(value: self.onBatteryShutdownAfterSecs, fieldNumber: 2)
}
if self.adcMultiplierOverride.bitPattern != 0 {
if self.adcMultiplierOverride != 0 {
try visitor.visitSingularFloatField(value: self.adcMultiplierOverride, fieldNumber: 3)
}
if self.waitBluetoothSecs != 0 {
@ -2636,6 +2741,7 @@ extension Config.DisplayConfig.OledType: SwiftProtobuf._ProtoNameProviding {
1: .same(proto: "OLED_SSD1306"),
2: .same(proto: "OLED_SH1106"),
3: .same(proto: "OLED_SH1107"),
4: .same(proto: "OLED_SH1107_128_64"),
]
}
@ -2794,7 +2900,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
if _storage._codingRate != 0 {
try visitor.visitSingularUInt32Field(value: _storage._codingRate, fieldNumber: 5)
}
if _storage._frequencyOffset.bitPattern != 0 {
if _storage._frequencyOffset != 0 {
try visitor.visitSingularFloatField(value: _storage._frequencyOffset, fieldNumber: 6)
}
if _storage._region != .unset {
@ -2818,7 +2924,7 @@ extension Config.LoRaConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplem
if _storage._sx126XRxBoostedGain != false {
try visitor.visitSingularBoolField(value: _storage._sx126XRxBoostedGain, fieldNumber: 13)
}
if _storage._overrideFrequency.bitPattern != 0 {
if _storage._overrideFrequency != 0 {
try visitor.visitSingularFloatField(value: _storage._overrideFrequency, fieldNumber: 14)
}
if _storage._paFanDisabled != false {
@ -3035,8 +3141,8 @@ extension Config.SessionkeyConfig: SwiftProtobuf.Message, SwiftProtobuf._Message
public static let _protobuf_nameMap = SwiftProtobuf._NameMap()
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
// Load everything into unknown fields
while try decoder.nextFieldNumber() != nil {}
while let _ = try decoder.nextFieldNumber() {
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {

View file

@ -1,6 +1,5 @@
// DO NOT EDIT.
// swift-format-ignore-file
// swiftlint:disable all
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: meshtastic/connection_status.proto
@ -8,6 +7,7 @@
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
import Foundation
import SwiftProtobuf
// If the compiler emits an error on this type, it is because this file
@ -20,7 +20,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP
typealias Version = _2
}
public struct DeviceConnectionStatus: Sendable {
public struct DeviceConnectionStatus {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -81,7 +81,7 @@ public struct DeviceConnectionStatus: Sendable {
///
/// WiFi connection status
public struct WifiConnectionStatus: Sendable {
public struct WifiConnectionStatus {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -114,7 +114,7 @@ public struct WifiConnectionStatus: Sendable {
///
/// Ethernet connection status
public struct EthernetConnectionStatus: Sendable {
public struct EthernetConnectionStatus {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -139,7 +139,7 @@ public struct EthernetConnectionStatus: Sendable {
///
/// Ethernet or WiFi connection status
public struct NetworkConnectionStatus: Sendable {
public struct NetworkConnectionStatus {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -167,7 +167,7 @@ public struct NetworkConnectionStatus: Sendable {
///
/// Bluetooth connection status
public struct BluetoothConnectionStatus: Sendable {
public struct BluetoothConnectionStatus {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -191,7 +191,7 @@ public struct BluetoothConnectionStatus: Sendable {
///
/// Serial connection status
public struct SerialConnectionStatus: Sendable {
public struct SerialConnectionStatus {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
@ -209,6 +209,15 @@ public struct SerialConnectionStatus: Sendable {
public init() {}
}
#if swift(>=5.5) && canImport(_Concurrency)
extension DeviceConnectionStatus: @unchecked Sendable {}
extension WifiConnectionStatus: @unchecked Sendable {}
extension EthernetConnectionStatus: @unchecked Sendable {}
extension NetworkConnectionStatus: @unchecked Sendable {}
extension BluetoothConnectionStatus: @unchecked Sendable {}
extension SerialConnectionStatus: @unchecked Sendable {}
#endif // swift(>=5.5) && canImport(_Concurrency)
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "meshtastic"

Some files were not shown because too many files have changed in this diff Show more