mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Merge branch 'main' into BetterReplies
This commit is contained in:
commit
3bac49ef1f
117 changed files with 2914 additions and 3270 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -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 = "";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1600"
|
||||
LastUpgradeVersion = "1630"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1600"
|
||||
LastUpgradeVersion = "1630"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)"
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ struct InvalidVersion: View {
|
|||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Label("close", systemImage: "xmark")
|
||||
Label("Close", systemImage: "xmark")
|
||||
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -39,4 +39,3 @@ struct WeatherConditionsCompactWidget: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ struct DateTimeText: View {
|
|||
if dateTime != nil && dateTime! >= sixMonthsAgo! {
|
||||
Text(" \(dateTime!.formattedDate(format: dateFormatString))")
|
||||
} else {
|
||||
Text("unknown.age")
|
||||
Text("Unknown Age")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ struct DirectMessagesHelp: View {
|
|||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Label("close", systemImage: "xmark")
|
||||
Label("Close", systemImage: "xmark")
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -154,6 +154,6 @@ struct ChannelList: View {
|
|||
.listStyle(.plain)
|
||||
}
|
||||
}
|
||||
.navigationTitle("channels")
|
||||
.navigationTitle("Channels")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ struct MessageText: View {
|
|||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
|
||||
}
|
||||
.contextMenu {
|
||||
MessageContextMenuItems(
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ Spacer()
|
|||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Label("close", systemImage: "xmark")
|
||||
Label("Close", systemImage: "xmark")
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
})
|
||||
])
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}),
|
||||
})
|
||||
])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ struct MetricsColumnDetail: View {
|
|||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Label("close", systemImage: "xmark")
|
||||
Label("Close", systemImage: "xmark")
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ struct NodeListFilter: View {
|
|||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Label("close", systemImage: "xmark")
|
||||
Label("Close", systemImage: "xmark")
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// })
|
||||
// }
|
||||
//}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 { }
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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 : "?")
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ struct DisplayConfig: View {
|
|||
}
|
||||
}
|
||||
|
||||
.navigationTitle("display.config")
|
||||
.navigationTitle("Display Config")
|
||||
.navigationBarItems(
|
||||
trailing: ZStack {
|
||||
ConnectedDevice(
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ?? "")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ struct AppLogFilter: View {
|
|||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Label("close", systemImage: "xmark")
|
||||
Label("Close", systemImage: "xmark")
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.buttonBorderShape(.capsule)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue