Merge branch 'main' into FixWaypointState

This commit is contained in:
Benjamin Faershtein 2025-05-09 09:22:01 -07:00 committed by GitHub
commit db5ec2f8cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
58 changed files with 8423 additions and 11508 deletions

File diff suppressed because it is too large Load diff

View file

@ -1785,7 +1785,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.6.1;
MARKETING_VERSION = 2.6.2;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
@ -1818,7 +1818,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 2.6.1;
MARKETING_VERSION = 2.6.2;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
@ -1849,7 +1849,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.6.1;
MARKETING_VERSION = 2.6.2;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@ -1881,7 +1881,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2.6.1;
MARKETING_VERSION = 2.6.2;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient.Widgets;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";

View file

@ -15,7 +15,7 @@ struct RestartNodeIntent: AppIntent {
func perform() async throws -> some IntentResult {
try await requestConfirmation(result: .result(dialog: "Reboot Node?"))
try await requestConfirmation(result: .result(dialog: "Reboot node?"))
if !BLEManager.shared.isConnected {
throw AppIntentErrors.AppIntentError.notConnected

View file

@ -66,7 +66,7 @@ enum MeshMapDistances: Double, CaseIterable, Identifiable {
var id: Double { self.rawValue }
var description: String {
let distanceFormatter = MKDistanceFormatter()
return String.localizedStringWithFormat("nodelist.filter.distance %@".localized, distanceFormatter.string(fromDistance: Double(self.rawValue)))
return String.localizedStringWithFormat("up to %@ away".localized, distanceFormatter.string(fromDistance: Double(self.rawValue)))
}
}
@ -78,11 +78,11 @@ enum UserTrackingModes: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .none:
return "map.usertrackingmode.none".localized
return "None".localized
case .follow:
return "map.usertrackingmode.follow".localized
return "Follow".localized
case .followWithHeading:
return "map.usertrackingmode.followwithheading".localized
return "Follow with heading".localized
}
}
var icon: String {
@ -117,21 +117,21 @@ enum LocationUpdateInterval: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .tenSeconds:
return "interval.ten.seconds".localized
return "Ten Seconds".localized
case .fifteenSeconds:
return "interval.fifteen.seconds".localized
return "Fifteen Seconds".localized
case .thirtySeconds:
return "interval.thirty.seconds".localized
return "Thirty Seconds".localized
case .fortyFiveSeconds:
return "interval.fortyfive.seconds".localized
return "Forty Five Seconds".localized
case .oneMinute:
return "interval.one.minute".localized
return "One Minute".localized
case .fiveMinutes:
return "interval.five.minutes".localized
return "Five Minutes".localized
case .tenMinutes:
return "interval.ten.minutes".localized
return "Ten Minutes".localized
case .fifteenMinutes:
return "interval.fifteen.minutes".localized
return "Fifteen Minutes".localized
}
}
}

View file

@ -45,21 +45,21 @@ enum InputEventChars: Int, CaseIterable, Identifiable {
switch self {
case .none:
return "inputevent.none".localized
return "None".localized
case .up:
return "inputevent.up".localized
return "Up".localized
case .down:
return "inputevent.down".localized
return "Down".localized
case .left:
return "inputevent.left".localized
return "Left".localized
case .right:
return "inputevent.right".localized
return "Right".localized
case .select:
return "inputevent.select".localized
return "Select".localized
case .back:
return "inputevent.back".localized
return "Back".localized
case .cancel:
return "inputevent.cancel".localized
return "Cancel".localized
}
}
func protoEnumValue() -> ModuleConfig.CannedMessageConfig.InputEventChar {

View file

@ -21,65 +21,60 @@ enum DeviceRoles: Int, CaseIterable, Identifiable {
case takTracker = 10
case repeater = 4
case router = 2
case routerClient = 3
case routerLate = 11
var id: Int { self.rawValue }
var name: String {
switch self {
case .client:
return "device.role.name.client".localized
return "Client".localized
case .clientMute:
return "device.role.name.clientMute".localized
return "Client Mute".localized
case .router:
return "device.role.name.router".localized
case .routerClient:
return "device.role.name.routerClient".localized
return "Router".localized
case .repeater:
return "device.role.name.repeater".localized
return "Repeater".localized
case .tracker:
return "device.role.name.tracker".localized
return "Tracker".localized
case .sensor:
return "device.role.name.sensor".localized
return "Sensor".localized
case .tak:
return "device.role.name.tak".localized
return "TAK".localized
case .takTracker:
return "device.role.name.takTracker".localized
return "TAK Tracker".localized
case .clientHidden:
return "device.role.name.clientHidden".localized
return "Client Hidden".localized
case .lostAndFound:
return "device.role.name.lostAndFound".localized
return "Lost and Found".localized
case .routerLate:
return "device.role.name.routerlate".localized
return "Router Late".localized
}
}
var description: String {
switch self {
case .client:
return "device.role.client".localized
return "App connected or stand alone messaging device.".localized
case .clientMute:
return "device.role.clientmute".localized
return "Device that does not forward packets from other devices.".localized
case .router:
return "device.role.router".localized
case .routerClient:
return "device.role.routerclient".localized
return "Infrastructure node on a tower or mountain top only. Not to be used for roofs or mobile nodes. Needs exceptional coverage. Visible in Nodes list.".localized
case .repeater:
return "device.role.repeater".localized
return "Infrastructure node on a tower or mountain top only. Not to be used for roofs or mobile nodes. Relays messages with minimal overhead. Not visible in Nodes list.".localized
case .tracker:
return "device.role.tracker".localized
return "Broadcasts GPS position packets as priority.".localized
case .sensor:
return "device.role.sensor".localized
return "Broadcasts telemetry packets as priority.".localized
case .tak:
return "device.role.tak".localized
return "Optimized for ATAK system communication, reduces routine broadcasts.".localized
case .takTracker:
return "device.role.taktracker".localized
return "Enables automatic TAK PLI broadcasts and reduces routine broadcasts.".localized
case .clientHidden:
return "device.role.clienthidden".localized
return "Device that only broadcasts as needed for stealth or power savings.".localized
case .lostAndFound:
return "device.role.lostandfound".localized
return "Broadcasts location as message to default channel regularly for to assist with device recovery.".localized
case .routerLate:
return "device.role.routerlate".localized
return "Infrastructure node that always rebroadcasts packets once but only after all other modes, ensuring additional coverage for local clusters. Visible in Nodes list.".localized
}
}
@ -89,7 +84,7 @@ enum DeviceRoles: Int, CaseIterable, Identifiable {
return "apps.iphone"
case .clientMute:
return "speaker.slash"
case .router, .routerClient, .routerLate:
case .router, .routerLate:
return "wifi.router"
case .repeater:
return "repeat"
@ -116,8 +111,6 @@ enum DeviceRoles: Int, CaseIterable, Identifiable {
return Config.DeviceConfig.Role.clientMute
case .router:
return Config.DeviceConfig.Role.router
case .routerClient:
return Config.DeviceConfig.Role.routerClient
case .repeater:
return Config.DeviceConfig.Role.repeater
case .tracker:
@ -152,17 +145,17 @@ enum RebroadcastModes: Int, CaseIterable, Identifiable {
var name: String {
switch self {
case .all:
return "All"
return "All".localized
case .allSkipDecoding:
return "All Skip Decoding"
return "All Skip Decoding".localized
case .localOnly:
return "Local Only"
return "Local Only".localized
case .knownOnly:
return "Known Only"
return "Known Only".localized
case .none:
return "None"
return "None".localized
case .corePortnums:
return "Core Portnums Only"
return "Core Portnums Only".localized
}
}
var description: String {

View file

@ -49,21 +49,21 @@ enum ScreenOnIntervals: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .fifteenSeconds:
return "interval.fifteen.seconds".localized
return "Fifteen Seconds".localized
case .thirtySeconds:
return "interval.thirty.seconds".localized
return "Thirty Seconds".localized
case .oneMinute:
return "interval.one.minute".localized
return "One Minute".localized
case .fiveMinutes:
return "interval.five.minutes".localized
return "Five Minutes".localized
case .tenMinutes:
return "interval.ten.minutes".localized
return "Ten Minutes".localized
case .fifteenMinutes:
return "interval.fifteen.minutes".localized
return "Fifteen Minutes".localized
case .thirtyMinutes:
return "interval.thirty.minutes".localized
return "Thirty Minutes".localized
case .oneHour:
return "interval.one.hour".localized
return "One Hour".localized
case .max:
return "Always On".localized
}
@ -87,17 +87,17 @@ enum ScreenCarouselIntervals: Int, CaseIterable, Identifiable {
case .off:
return "off".localized
case .fifteenSeconds:
return "interval.fifteen.seconds".localized
return "Fifteen Seconds".localized
case .thirtySeconds:
return "interval.thirty.seconds".localized
return "Thirty Seconds".localized
case .oneMinute:
return "interval.one.minute".localized
return "One Minute".localized
case .fiveMinutes:
return "interval.five.minutes".localized
return "Five Minutes".localized
case .tenMinutes:
return "interval.ten.minutes".localized
return "Ten Minutes".localized
case .fifteenMinutes:
return "interval.fifteen.minutes".localized
return "Fifteen Minutes".localized
}
}
}
@ -149,13 +149,13 @@ enum DisplayModes: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .defaultMode:
return "default.128x64.screen.layout".localized
return "Default 128x64 screen layout".localized
case .twoColor:
return "optimized.for.2.color.displays".localized
return "Optimized for 2 color displays".localized
case .inverted:
return "inverted.top.bar.for.2.color.display".localized
return "Inverted top bar for 2 Color display".localized
case .color:
return "tft.full.color.displays".localized
return "TFT Full Color Displays".localized
}
}
func protoEnumValue() -> Config.DisplayConfig.DisplayMode {

View file

@ -24,19 +24,19 @@ enum NagIntervals: Int, CaseIterable, Identifiable {
case .unset:
return "Unset".localized
case .oneSecond:
return "interval.one.second".localized
return "One Second".localized
case .fiveSeconds:
return "interval.five.seconds".localized
return "Five Seconds".localized
case .tenSeconds:
return "interval.ten.seconds".localized
return "Ten Seconds".localized
case .fifteenSeconds:
return "interval.fifteen.seconds".localized
return "Fifteen Seconds".localized
case .thirtySeconds:
return "interval.thirty.seconds".localized
return "Thirty Seconds".localized
case .oneMinute:
return "interval.one.minute".localized
return "One Minute".localized
case .fiveMinutes:
return "interval.five.minutes".localized
return "Five Minutes".localized
}
}
}
@ -61,23 +61,23 @@ enum OutputIntervals: Int, CaseIterable, Identifiable {
case .unset:
return "Unset".localized
case .oneSecond:
return "interval.one.second".localized
return "One Second".localized
case .twoSeconds:
return "interval.two.seconds".localized
return "Two Seconds".localized
case .threeSeconds:
return "interval.three.seconds".localized
return "Three Seconds".localized
case .fourSeconds:
return "interval.four.seconds".localized
return "Four Seconds".localized
case .fiveSeconds:
return "interval.five.seconds".localized
return "Five Seconds".localized
case .tenSeconds:
return "interval.ten.seconds".localized
return "Ten Seconds".localized
case .fifteenSeconds:
return "interval.fifteen.seconds".localized
return "Fifteen Seconds".localized
case .thirtySeconds:
return "interval.thirty.seconds".localized
return "Thirty Seconds".localized
case .oneMinute:
return "interval.one.minute".localized
return "One Minute".localized
}
}
}
@ -100,25 +100,25 @@ enum SenderIntervals: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .off:
return "off".localized
return "Off".localized
case .fifteenSeconds:
return "interval.fifteen.seconds".localized
return "Fifteen Seconds".localized
case .thirtySeconds:
return "interval.thirty.seconds".localized
return "Thirty Seconds".localized
case .fortyFiveSeconds:
return "interval.fortyfive.seconds".localized
return "Forty Five Seconds".localized
case .oneMinute:
return "interval.one.minute".localized
return "One Minute".localized
case .fiveMinutes:
return "interval.five.minutes".localized
return "Five Minutes".localized
case .tenMinutes:
return "interval.ten.minutes".localized
return "Ten Minutes".localized
case .fifteenMinutes:
return "interval.fifteen.minutes".localized
return "Fifteen Minutes".localized
case .thirtyMinutes:
return "interval.thirty.minutes".localized
return "Thirty Minutes".localized
case .oneHour:
return "interval.one.hour".localized
return "One Hour".localized
}
}
}
@ -153,49 +153,49 @@ enum UpdateIntervals: Int, CaseIterable, Identifiable {
switch self {
case .tenSeconds:
return "interval.ten.seconds".localized
return "Ten Seconds".localized
case .fifteenSeconds:
return "interval.fifteen.seconds".localized
return "Fifteen Seconds".localized
case .thirtySeconds:
return "interval.thirty.seconds".localized
return "Thirty Seconds".localized
case .fortyFiveSeconds:
return "interval.fortyfive.seconds".localized
return "Forty Five Seconds".localized
case .oneMinute:
return "interval.one.minute".localized
return "One Minute".localized
case .twoMinutes:
return "interval.two.minutes".localized
return "Two Minutes".localized
case .fiveMinutes:
return "interval.five.minutes".localized
return "Five Minutes".localized
case .tenMinutes:
return "interval.ten.minutes".localized
return "Ten Minutes".localized
case .fifteenMinutes:
return "interval.fifteen.minutes".localized
return "Fifteen Minutes".localized
case .thirtyMinutes:
return "interval.thirty.minutes".localized
return "Thirty Minutes".localized
case .oneHour:
return "interval.one.hour".localized
return "One Hour".localized
case .twoHours:
return "interval.two.hours".localized
return "Two Hours".localized
case .threeHours:
return "interval.three.hours".localized
return "Three Hours".localized
case .fourHours:
return "interval.four.hours".localized
return "Four Hours".localized
case .fiveHours:
return "interval.five.hours".localized
return "Five Hours".localized
case .sixHours:
return "interval.six.hours".localized
return "Six Hours".localized
case .twelveHours:
return "interval.twelve.hours".localized
return "Twelve Hours".localized
case .eighteenHours:
return "interval.eighteen.hours".localized
return "Eighteen Hours".localized
case .twentyFourHours:
return "interval.twentyfour.hours".localized
return "Twenty Four Hours".localized
case .thirtySixHours:
return "interval.thirtysix.hours".localized
return "Thirty Six Hours".localized
case .fortyeightHours:
return "interval.fortyeight.hours".localized
return "Forty Eight Hours".localized
case .seventyTwoHours:
return "interval.seventytwo.hours".localized
return "Seventy Two Hours".localized
}
}
}

View file

@ -105,27 +105,27 @@ enum RegionCodes: Int, CaseIterable, Identifiable {
case .in:
return "India".localized
case .nz865:
return "New Zealand 865mhz".localized
return "New Zealand 865MHz".localized
case .th:
return "Thailand".localized
case .ua433:
return "Ukraine 433mhz".localized
return "Ukraine 433MHz".localized
case .ua868:
return "Ukraine 868mhz".localized
return "Ukraine 868MHz".localized
case .lora24:
return "2.4 Ghz".localized
case .my433:
return "Malaysia 433mhz".localized
return "Malaysia 433MHz".localized
case .my919:
return "Malaysia 919mhz".localized
return "Malaysia 919MHz".localized
case .sg923:
return "Singapore 923mhz".localized
return "Singapore 923MHz".localized
case .ph433:
return "Philippines 433mhz".localized
return "Philippines 433MHz".localized
case .ph868:
return "Philippines 868mhz".localized
return "Philippines 868MHz".localized
case .ph915:
return "Philippines 915mhz".localized
return "Philippines 915MHz".localized
}
}
var dutyCycle: Int {
@ -280,7 +280,6 @@ enum ModemPresets: Int, CaseIterable, Identifiable {
case longFast = 0
case longSlow = 1
case longModerate = 7
case vLongSlow = 2
case medSlow = 3
case medFast = 4
case shortSlow = 5
@ -295,19 +294,17 @@ enum ModemPresets: Int, CaseIterable, Identifiable {
case .longSlow:
return "Long Range - Slow".localized
case .longModerate:
return "long.range.moderate".localized
case .vLongSlow:
return "very.long.range.slow".localized
return "Long Range - Moderate".localized
case .medSlow:
return "medium.range.slow".localized
return "Medium Range - Slow".localized
case .medFast:
return "medium.range.fast".localized
return "Medium Range - Fast".localized
case .shortSlow:
return "short.range.slow".localized
return "Short Range - Slow".localized
case .shortFast:
return "short.range.fast".localized
return "Short Range - Fast".localized
case .shortTurbo:
return "short.range.turbo".localized
return "Short Range - Turbo".localized
}
}
var name: String {
@ -318,8 +315,6 @@ enum ModemPresets: Int, CaseIterable, Identifiable {
return "LongSlow"
case .longModerate:
return "LongModerate"
case .vLongSlow:
return "VLongFast"
case .medSlow:
return "MediumSlow"
case .medFast:
@ -340,8 +335,6 @@ enum ModemPresets: Int, CaseIterable, Identifiable {
return -7.5
case .longModerate:
return -17.5
case .vLongSlow:
return -20
case .medSlow:
return -15
case .medFast:
@ -362,8 +355,6 @@ enum ModemPresets: Int, CaseIterable, Identifiable {
return Config.LoRaConfig.ModemPreset.longSlow
case .longModerate:
return Config.LoRaConfig.ModemPreset.longModerate
case .vLongSlow:
return Config.LoRaConfig.ModemPreset.veryLongSlow
case .medSlow:
return Config.LoRaConfig.ModemPreset.mediumSlow
case .medFast:

View file

@ -46,21 +46,21 @@ enum Tapbacks: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .wave:
return "tapback.wave".localized
return "Wave".localized
case .heart:
return "tapback.heart".localized
return "Heart".localized
case .thumbsUp:
return "tapback.thumbsup".localized
return "Thumbs Up".localized
case .thumbsDown:
return "tapback.thumbsdown".localized
return "Thumbs Down".localized
case .haHa:
return "tapback.haha".localized
return "HaHa".localized
case .exclamation:
return "tapback.exclamation".localized
return "Exclamation".localized
case .question:
return "tapback.question".localized
return "Question".localized
case .poop:
return "tapback.poop".localized
return "Poop".localized
}
}
}

View file

@ -21,17 +21,17 @@ enum GpsFormats: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .gpsFormatDec:
return "gpsformat.dec".localized
return "Decimal Degrees Format".localized
case .gpsFormatDms:
return "gpsformat.dms".localized
return "Degrees Minutes Seconds".localized
case .gpsFormatUtm:
return "gpsformat.utm".localized
return "Universal Transverse Mercator".localized
case .gpsFormatMgrs:
return "gpsformat.mgrs".localized
return "Military Grid Reference System".localized
case .gpsFormatOlc:
return "gpsformat.olc".localized
return "Open Location Code (aka Plus Codes)".localized
case .gpsFormatOsgr:
return "gpsformat.osgr".localized
return "Ordnance Survey Grid Reference".localized
}
}
func protoEnumValue() -> Config.DisplayConfig.GpsCoordinateFormat {
@ -73,29 +73,29 @@ enum GpsUpdateIntervals: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .thirtySeconds:
return "interval.thirty.seconds".localized
return "Thirty Seconds".localized
case .oneMinute:
return "interval.one.minute".localized
return "One Minute".localized
case .twoMinutes:
return "interval.two.minutes".localized
return "Two Minutes".localized
case .fiveMinutes:
return "interval.five.minutes".localized
return "Five Minutes".localized
case .tenMinutes:
return "interval.ten.minutes".localized
return "Ten Minutes".localized
case .fifteenMinutes:
return "interval.fifteen.minutes".localized
return "Fifteen Minutes".localized
case .thirtyMinutes:
return "interval.thirty.minutes".localized
return "Thirty Minutes".localized
case .oneHour:
return "interval.one.hour".localized
return "One Hour".localized
case .sixHours:
return "interval.six.hours".localized
return "Six Hours".localized
case .twelveHours:
return "interval.twelve.hours".localized
return "Twelve Hours".localized
case .twentyFourHours:
return "interval.twentyfour.hours".localized
return "Twenty Four Hours".localized
case .maxInt32:
return "on.boot".localized
return "On Boot Only".localized
}
}
}

View file

@ -20,34 +20,34 @@ enum ActivityType: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .walking:
return "routes.activitytype.walking".localized
return "Walking".localized
case .hiking:
return "routes.activitytype.hiking".localized
return "Hiking".localized
case .biking:
return "routes.activitytype.biking".localized
return "Biking".localized
case .driving:
return "routes.activitytype.driving".localized
return "Driving".localized
case .overlanding:
return "routes.activitytype.overlanding".localized
return "Overlanding".localized
case .skiing:
return "routes.activitytype.skiing".localized
return "Skiing".localized
}
}
var fileNameString: String {
switch self {
case .walking:
return "routes.activitytype.filename.walking".localized
return "walk".localized
case .hiking:
return "routes.activitytype.filename.hiking".localized
return "hiking".localized
case .biking:
return "routes.activitytype.filename.biking".localized
return "biking".localized
case .driving:
return "routes.activitytype.filename.driving".localized
return "driving".localized
case .overlanding:
return "routes.activitytype.filename.overlanding".localized
return "overlanding".localized
case .skiing:
return "routes.activitytype.filename.skiing".localized
return "skiing".localized
}
}
}

View file

@ -120,15 +120,15 @@ enum SerialModeTypes: Int, CaseIterable, Identifiable {
case .default:
return "Default".localized
case .simple:
return "serial.mode.simple".localized
return "Simple".localized
case .proto:
return "serial.mode.proto".localized
return "Protobufs".localized
case .txtmsg:
return "serial.mode.txtmsg".localized
return "Text Message".localized
case .nmea:
return "serial.mode.nmea".localized
return "NMEA Positions".localized
case .caltopo:
return "serial.mode.caltopo".localized
return "CALTOPO".localized
}
}
func protoEnumValue() -> ModuleConfig.SerialConfig.Serial_Mode {
@ -168,19 +168,19 @@ enum SerialTimeoutIntervals: Int, CaseIterable, Identifiable {
case .unset:
return "Unset".localized
case .oneSecond:
return "interval.one.second".localized
return "One Second".localized
case .fiveSeconds:
return "interval.five.seconds".localized
return "Five Seconds".localized
case .tenSeconds:
return "interval.ten.seconds".localized
return "Ten Seconds".localized
case .fifteenSeconds:
return "interval.fifteen.seconds".localized
return "Fifteen Seconds".localized
case .thirtySeconds:
return "interval.thirty.seconds".localized
return "Thirty Seconds".localized
case .oneMinute:
return "interval.one.minute".localized
return "One Minute".localized
case .fiveMinutes:
return "interval.five.minutes".localized
return "Five Minutes".localized
}
}
}

View file

@ -20,17 +20,17 @@ enum Aqi: Int, CaseIterable, Identifiable {
var description: String {
switch self {
case .good:
return "telemetry.good".localized
return "Good".localized
case .moderate:
return "telemetry.moderate".localized
return "Moderate".localized
case .sensitive:
return "telemetry.sensitive".localized
return "Unhealthy for Sensitive Groups".localized
case .unhealthy:
return "telementry.unhealthy".localized
return "Unhealthy".localized
case .veryUnhealthy:
return "telementry.veryUnhealthy".localized
return "Very Unhealthy".localized
case .hazardous:
return "telementry.hazardous".localized
return "Hazardous".localized
}
}
var color: Color {

View file

@ -30,11 +30,11 @@ extension Date {
let hour = Calendar.current.component(.hour, from: self)
switch hour {
case 6..<12: return "relativetimeofday.morning".localized
case 12: return "relativetimeofday.midday".localized
case 13..<17: return "relativetimeofday.afternoon".localized
case 17..<22: return "relativetimeofday.evening".localized
default: return "relativetimeofday.nighttime".localized
case 6..<12: return "Morning".localized
case 12: return "Midday".localized
case 13..<17: return "Afternoon".localized
case 17..<22: return "Evening".localized
default: return "Nighttime".localized
}
}
}

View file

@ -484,7 +484,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
Logger.data.error("Error Updating Core Data BluetoothConfigEntity: \(nsError, privacy: .public)")
}
let logString = String.localizedStringWithFormat("mesh.log.traceroute.sent %@".localized, destNum.toHex())
let logString = String.localizedStringWithFormat("Sent a Trace Route Request to node: %@".localized, destNum.toHex())
Logger.mesh.info("🪧 \(logString, privacy: .public)")
} catch {
@ -498,13 +498,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
guard connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected else { return }
if FROMRADIO_characteristic == nil {
Logger.mesh.error("🚨 \("firmware.version.unsupported".localized, privacy: .public)")
Logger.mesh.error("🚨 \("Unsupported Firmware Version Detected, unable to connect to device.".localized, privacy: .public)")
invalidVersion = true
return
} else {
let nodeName = connectedPeripheral?.peripheral.name ?? "Unknown".localized
let logString = String.localizedStringWithFormat("mesh.log.wantconfig %@".localized, nodeName)
let logString = String.localizedStringWithFormat("Issuing Want Config to %@".localized, nodeName)
Logger.mesh.info("🛎️ \(logString, privacy: .public)")
// BLE Characteristics discovered, issue wantConfig
var toRadio: ToRadio = ToRadio()
@ -739,7 +739,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let supportedVersion = connectedVersion == "0.0.0" || self.minimumVersion.compare(connectedVersion, options: .numeric) == .orderedAscending || minimumVersion.compare(connectedVersion, options: .numeric) == .orderedSame
if !supportedVersion {
invalidVersion = true
lastConnectionError = "🚨" + "update.firmware".localized
lastConnectionError = "🚨" + "Update Your Firmware".localized
return
}
}
@ -954,7 +954,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let nsError = error as NSError
Logger.data.error("Error Updating Core Data TraceRouteHop: \(nsError, privacy: .public)")
}
let logString = String.localizedStringWithFormat("mesh.log.traceroute.received.route %@".localized, routeString)
let logString = String.localizedStringWithFormat("Trace Route request returned: %@".localized, routeString)
Logger.mesh.info("🪧 \(logString, privacy: .public)")
}
case .neighborinfoApp:
@ -1058,7 +1058,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
connectTo(peripheral: preferredPeripheral!.peripheral)
}
let nodeName = connectedPeripheral?.peripheral.name ?? "Unknown".localized
let logString = String.localizedStringWithFormat("mesh.log.textmessage.send.failed %@".localized, nodeName)
let logString = String.localizedStringWithFormat("Message Send Failed, not properly connected to %@".localized, nodeName)
Logger.mesh.info("🚫 \(logString, privacy: .public)")
success = false
@ -1144,7 +1144,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
let logString = String.localizedStringWithFormat("mesh.log.textmessage.sent %@ %@ %@".localized, String(newMessage.messageId), fromUserNum.toHex(), toUserNum.toHex())
let logString = String.localizedStringWithFormat("Sent message %@ from %@ to %@".localized, String(newMessage.messageId), fromUserNum.toHex(), toUserNum.toHex())
Logger.mesh.info("💬 \(logString, privacy: .public)")
do {
@ -1192,7 +1192,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
guard let binaryData: Data = try? toRadio.serializedData() else {
return false
}
let logString = String.localizedStringWithFormat("mesh.log.waypoint.sent %@".localized, String(fromNodeNum))
let logString = String.localizedStringWithFormat("Sent a Waypoint Packet from: %@".localized, String(fromNodeNum))
Logger.mesh.info("📍 \(logString, privacy: .public)")
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
@ -1356,7 +1356,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
let logString = String.localizedStringWithFormat("mesh.log.sharelocation %@".localized, String(fromNodeNum))
let logString = String.localizedStringWithFormat("Sent a Position Packet from the Apple device GPS to node: %@".localized, String(fromNodeNum))
Logger.services.debug("📍 \(logString, privacy: .public)")
return true
} else {
@ -1711,7 +1711,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
self.connectedPeripheral.peripheral.writeValue(binaryData, for: self.TORADIO_characteristic, type: .withResponse)
let logString = String.localizedStringWithFormat("mesh.log.channel.sent %@ %d".localized, String(connectedPeripheral.num), chan.index)
let logString = String.localizedStringWithFormat("Sent a Channel for: %@ Channel Index %d".localized, String(connectedPeripheral.num), chan.index)
Logger.mesh.info("🎛️ \(logString, privacy: .public)")
}
}
@ -1740,7 +1740,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
self.connectedPeripheral.peripheral.writeValue(binaryData, for: self.TORADIO_characteristic, type: .withResponse)
let logString = String.localizedStringWithFormat("mesh.log.lora.config.sent %@".localized, String(connectedPeripheral.num))
let logString = String.localizedStringWithFormat("Sent a LoRa.Config for: %@".localized, String(connectedPeripheral.num))
Logger.mesh.info("📻 \(logString, privacy: .public)")
}
@ -2660,7 +2660,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
let logString = String.localizedStringWithFormat("mesh.log.cannedmessages.messages.get %@".localized, String(connectedPeripheral.num))
let logString = String.localizedStringWithFormat("Requested Canned Messages Module Messages for node: %@".localized, String(connectedPeripheral.num))
Logger.mesh.info("🥫 \(logString, privacy: .public)")
return true
}

View file

@ -103,7 +103,7 @@ func moduleConfig (config: ModuleConfig, context: NSManagedObjectContext, nodeNu
func myInfoPacket (myInfo: MyNodeInfo, peripheralId: String, context: NSManagedObjectContext) -> MyInfoEntity? {
let logString = String.localizedStringWithFormat("mesh.log.myinfo %@".localized, String(myInfo.myNodeNum))
let logString = String.localizedStringWithFormat("MyInfo received: %@".localized, String(myInfo.myNodeNum))
Logger.mesh.info(" \(logString, privacy: .public)")
let fetchMyInfoRequest = MyInfoEntity.fetchRequest()
@ -209,7 +209,7 @@ func channelPacket (channel: Channel, fromNum: Int64, context: NSManagedObjectCo
func deviceMetadataPacket (metadata: DeviceMetadata, fromNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
if metadata.isInitialized {
let logString = String.localizedStringWithFormat("mesh.log.device.metadata.received %@".localized, fromNum.toHex())
let logString = String.localizedStringWithFormat("Device Metadata received from: %@".localized, fromNum.toHex())
Logger.mesh.info("🏷️ \(logString, privacy: .public)")
let fetchedNodeRequest = NodeInfoEntity.fetchRequest()
@ -261,7 +261,7 @@ func deviceMetadataPacket (metadata: DeviceMetadata, fromNum: Int64, sessionPass
func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObjectContext) -> NodeInfoEntity? {
let logString = String.localizedStringWithFormat("mesh.log.nodeinfo.received %@".localized, String(nodeInfo.num))
let logString = String.localizedStringWithFormat("Node info received for: %@".localized, String(nodeInfo.num))
Logger.mesh.info("📟 \(logString, privacy: .public)")
guard nodeInfo.num > 0 else { return nil }
@ -472,7 +472,7 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
if !cmmc.messages.isEmpty {
let logString = String.localizedStringWithFormat("mesh.log.cannedmessages.messages.received %@".localized, packet.from.toHex())
let logString = String.localizedStringWithFormat("Canned Messages Messages Received For: %@".localized, packet.from.toHex())
Logger.mesh.info("🥫 \(logString, privacy: .public)")
let fetchNodeRequest = NodeInfoEntity.fetchRequest()
@ -582,7 +582,7 @@ func adminResponseAck (packet: MeshPacket, context: NSManagedObjectContext) {
}
func paxCounterPacket (packet: MeshPacket, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.paxcounter %@".localized, String(packet.from))
let logString = String.localizedStringWithFormat("PAX Counter message received from: %@".localized, String(packet.from))
Logger.mesh.info("🧑‍🤝‍🧑 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -626,7 +626,7 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana
let routingError = RoutingError(rawValue: routingMessage.errorReason.rawValue)
let routingErrorString = routingError?.display ?? "Unknown".localized
let logString = String.localizedStringWithFormat("mesh.log.routing.message %@ %@".localized, String(packet.decoded.requestID), routingErrorString)
let logString = String.localizedStringWithFormat("Routing received for RequestID: %@ Ack Status: %@".localized, String(packet.decoded.requestID), routingErrorString)
Logger.mesh.info("🕸️ \(logString, privacy: .public)")
let fetchMessageRequest = MessageEntity.fetchRequest()
@ -686,7 +686,7 @@ 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))
let logString = String.localizedStringWithFormat("Telemetry received for: %@".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
@ -875,7 +875,7 @@ func textMessageAppPacket(
}
if messageText?.count ?? 0 > 0 {
Logger.mesh.info("💬 \("mesh.log.textmessage.received".localized, privacy: .public)")
Logger.mesh.info("💬 \("Message received from the text message app.".localized, privacy: .public)")
let messageUsers = UserEntity.fetchRequest()
messageUsers.predicate = NSPredicate(format: "num IN %@", [packet.to, packet.from])
do {
@ -1035,8 +1035,10 @@ func textMessageAppPacket(
}
}
func waypointPacket(packet: MeshPacket, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.waypoint.received %@".localized, String(packet.from))
func waypointPacket (packet: MeshPacket, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("Waypoint Packet received from node: %@".localized, String(packet.from))
Logger.mesh.info("📍 \(logString, privacy: .public)")
do {

View file

@ -129,7 +129,7 @@ public func clearCoreDataDatabase(context: NSManagedObjectContext, includeRoutes
func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.nodeinfo.received %@".localized, packet.from.toHex())
let logString = String.localizedStringWithFormat("Node info received for: %@".localized, packet.from.toHex())
Logger.mesh.info("📟 \(logString, privacy: .public)")
guard packet.from > 0 else { return }
@ -312,7 +312,7 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.position.received %@".localized, String(packet.from))
let logString = String.localizedStringWithFormat("Position Packet received from node: %@".localized, String(packet.from))
Logger.mesh.info("📍 \(logString, privacy: .public)")
let fetchNodePositionRequest = NodeInfoEntity.fetchRequest()
@ -406,7 +406,7 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext)
func upsertBluetoothConfigPacket(config: Config.BluetoothConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.bluetooth.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("Bluetooth config received: %@".localized, String(nodeNum))
Logger.mesh.info("📶 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -450,7 +450,7 @@ func upsertBluetoothConfigPacket(config: Config.BluetoothConfig, nodeNum: Int64,
func upsertDeviceConfigPacket(config: Config.DeviceConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.device.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("Device config received: %@".localized, String(nodeNum))
Logger.mesh.info("📟 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -505,7 +505,7 @@ func upsertDeviceConfigPacket(config: Config.DeviceConfig, nodeNum: Int64, sessi
func upsertDisplayConfigPacket(config: Config.DisplayConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.display.config %@".localized, nodeNum.toHex())
let logString = String.localizedStringWithFormat("Display config received: %@".localized, nodeNum.toHex())
Logger.data.info("🖥️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -567,7 +567,7 @@ func upsertDisplayConfigPacket(config: Config.DisplayConfig, nodeNum: Int64, ses
func upsertLoRaConfigPacket(config: Config.LoRaConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.lora.config %@".localized, nodeNum.toHex())
let logString = String.localizedStringWithFormat("LoRa config received: %@".localized, nodeNum.toHex())
Logger.data.info("📻 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -638,7 +638,7 @@ func upsertLoRaConfigPacket(config: Config.LoRaConfig, nodeNum: Int64, sessionPa
func upsertNetworkConfigPacket(config: Config.NetworkConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.network.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("Network config received: %@".localized, String(nodeNum))
Logger.data.info("🌐 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -687,7 +687,7 @@ func upsertNetworkConfigPacket(config: Config.NetworkConfig, nodeNum: Int64, ses
func upsertPositionConfigPacket(config: Config.PositionConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.position.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("Position config received: %@".localized, String(nodeNum))
Logger.data.info("🗺️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -750,7 +750,7 @@ func upsertPositionConfigPacket(config: Config.PositionConfig, nodeNum: Int64, s
}
func upsertPowerConfigPacket(config: Config.PowerConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.power.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("Power config received: %@".localized, String(nodeNum))
Logger.data.info("🗺️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -863,7 +863,7 @@ func upsertSecurityConfigPacket(config: Config.SecurityConfig, nodeNum: Int64, s
func upsertAmbientLightingModuleConfigPacket(config: ModuleConfig.AmbientLightingConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.ambientlighting.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("Ambient Lighting module config received: %@".localized, String(nodeNum))
Logger.data.info("🏮 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -916,7 +916,7 @@ func upsertAmbientLightingModuleConfigPacket(config: ModuleConfig.AmbientLightin
func upsertCannedMessagesModuleConfigPacket(config: ModuleConfig.CannedMessageConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.cannedmessage.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("Canned Message module config received: %@".localized, String(nodeNum))
Logger.data.info("🥫 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -975,7 +975,7 @@ func upsertCannedMessagesModuleConfigPacket(config: ModuleConfig.CannedMessageCo
func upsertDetectionSensorModuleConfigPacket(config: ModuleConfig.DetectionSensorConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.detectionsensor.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("Detection Sensor module config received: %@".localized, String(nodeNum))
Logger.data.info("🕵️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -1032,7 +1032,7 @@ func upsertDetectionSensorModuleConfigPacket(config: ModuleConfig.DetectionSenso
func upsertExternalNotificationModuleConfigPacket(config: ModuleConfig.ExternalNotificationConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.externalnotification.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("External Notification module config received: %@".localized, String(nodeNum))
Logger.data.info("📣 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -1143,7 +1143,7 @@ func upsertPaxCounterModuleConfigPacket(config: ModuleConfig.PaxcounterConfig, n
func upsertRtttlConfigPacket(ringtone: String, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.ringtone.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("RTTTL Ringtone config received: %@".localized, String(nodeNum))
Logger.data.info("⛰️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -1183,7 +1183,7 @@ func upsertRtttlConfigPacket(ringtone: String, nodeNum: Int64, sessionPasskey: D
func upsertMqttModuleConfigPacket(config: ModuleConfig.MQTTConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.mqtt.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("MQTT module config received: %@".localized, String(nodeNum))
Logger.data.info("🌉 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -1245,7 +1245,7 @@ func upsertMqttModuleConfigPacket(config: ModuleConfig.MQTTConfig, nodeNum: Int6
func upsertRangeTestModuleConfigPacket(config: ModuleConfig.RangeTestConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.rangetest.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("Range Test module config received: %@".localized, String(nodeNum))
Logger.data.info("⛰️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -1289,7 +1289,7 @@ func upsertRangeTestModuleConfigPacket(config: ModuleConfig.RangeTestConfig, nod
func upsertSerialModuleConfigPacket(config: ModuleConfig.SerialConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.serial.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("Serial module config received: %@".localized, String(nodeNum))
Logger.data.info("🤖 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -1344,7 +1344,7 @@ func upsertSerialModuleConfigPacket(config: ModuleConfig.SerialConfig, nodeNum:
func upsertStoreForwardModuleConfigPacket(config: ModuleConfig.StoreForwardConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.storeforward.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("Store & Forward module config received: %@".localized, String(nodeNum))
Logger.data.info("📬 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
@ -1393,7 +1393,7 @@ func upsertStoreForwardModuleConfigPacket(config: ModuleConfig.StoreForwardConfi
func upsertTelemetryModuleConfigPacket(config: ModuleConfig.TelemetryConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.telemetry.config %@".localized, String(nodeNum))
let logString = String.localizedStringWithFormat("Telemetry module config received: %@".localized, String(nodeNum))
Logger.data.info("📈 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()

View file

@ -13,10 +13,10 @@
return "tip.channels.share"
}
var title: Text {
Text("tip.channels.share.title")
Text("Sharing Meshtastic Channels")
}
var message: Text? {
Text("tip.channels.share.message")
Text("A Meshtastic QR code contains the LoRa config and channel values needed for radios to communicate. You can share a complete channel configuration using the Replace Channels option, if you choose Add Channels your shared channels will be added to the channels on the receiving radio.")
}
var image: Image? {
Image(systemName: "qrcode")
@ -29,10 +29,10 @@ struct CreateChannelsTip: Tip {
return "tip.channels.create"
}
var title: Text {
Text("tip.channels.create.title")
Text("Manage Channels")
}
var message: Text? {
Text("tip.channels.create.message")
Text("Most data on your mesh is sent over the primary channel. You can set up secondary channels to create additional messaging groups secured by their own key. [Channel config tips](https://meshtastic.org/docs/configuration/tips/)")
}
var image: Image? {
Image(systemName: "fibrechannel")
@ -45,10 +45,10 @@ struct AdminChannelTip: Tip {
return "tip.channel.admin"
}
var title: Text {
Text("tip.channel.admin.title")
Text("Administration Enabled")
}
var message: Text? {
Text("tip.channel.admin.message")
Text("Select a node from the drop down to manage connected or remote devices.")
}
var image: Image? {
Image(systemName: "fibrechannel")

View file

@ -16,7 +16,7 @@ struct MessagesTip: Tip {
Text("Messages")
}
var message: Text? {
Text("tip.messages.message")
Text("You can send and receive channel (group chats) and direct messages. From any message you can long press to see available actions like copy, reply, tapback and delete as well as delivery details.")
}
var image: Image? {
Image(systemName: "bubble.left.and.bubble.right")

View file

@ -46,7 +46,7 @@ struct Connect: View {
VStack {
List {
if bleManager.isSwitchedOn {
Section(header: Text("connected.radio").font(.title)) {
Section(header: Text("Connected Radio").font(.title)) {
if let connectedPeripheral = bleManager.connectedPeripheral, connectedPeripheral.peripheral.state == .connected {
TipView(BluetoothConnectionTip(), arrowEdge: .bottom)
VStack(alignment: .leading) {
@ -116,7 +116,7 @@ struct Connect: View {
#endif
}
} label: {
Label("mesh.live.activity", systemImage: liveActivityStarted ? "stop" : "play")
Label("Mesh Live Activity", systemImage: liveActivityStarted ? "stop" : "play")
}
#endif
Text("Num: \(String(node!.num))")
@ -139,7 +139,7 @@ struct Connect: View {
NavigationLink {
LoRaConfig(node: node)
} label: {
Label("set.region", systemImage: "globe.americas.fill")
Label("Set LoRa Region", systemImage: "globe.americas.fill")
.foregroundColor(.red)
.font(.title)
}
@ -156,7 +156,7 @@ struct Connect: View {
.frame(width: 60, height: 60)
.padding(.trailing)
if bleManager.timeoutTimerCount == 0 {
Text("connecting")
Text("Connecting . .")
.font(.title2)
.foregroundColor(.orange)
} else {
@ -189,7 +189,7 @@ struct Connect: View {
.foregroundColor(.red)
.frame(width: 60, height: 60)
.padding(.trailing)
Text("not.connected").font(.title3)
Text("No device connected").font(.title3)
}
.padding()
}

View file

@ -17,7 +17,7 @@ struct InvalidVersion: View {
VStack {
Text("update.firmware")
Text("Update Your Firmware")
.font(.largeTitle)
.foregroundColor(.orange)

View file

@ -40,13 +40,13 @@ struct ContentView: View {
router: appState.router
)
.tabItem {
Label("nodes", systemImage: "flipphone")
Label("Nodes", systemImage: "flipphone")
}
.tag(NavigationState.Tab.nodes)
MeshMap(router: appState.router)
.tabItem {
Label("map", systemImage: "map")
Label("Mesh Map", systemImage: "map")
}
.tag(NavigationState.Tab.map)

View file

@ -47,13 +47,13 @@ enum LoRaSignalStrength: Int {
var description: String {
switch self {
case .none:
return "lora.signal.strength.none".localized
return "None".localized
case .bad:
return "lora.signal.strength.bad".localized
return "Bad".localized
case .fair:
return "lora.signal.strength.fair".localized
return "Fair".localized
case .good:
return "lora.signal.strength.good".localized
return "Good".localized
}
}
}

View file

@ -51,7 +51,7 @@ struct MessageContextMenuItems: View {
Image(systemName: "doc.on.doc")
}
Menu("message.details") {
Menu("Message Details") {
VStack {
let messageDate = Date(timeIntervalSince1970: TimeInterval(message.messageTimestamp))
Text("\(messageDate.formattedDate(format: MessageText.dateFormatString))").foregroundColor(.gray)
@ -69,8 +69,8 @@ struct MessageContextMenuItems: View {
}
if isCurrentUser && message.receivedACK {
VStack {
Text("received.ack") + Text(": \(message.receivedACK ? "✔️" : "")")
Text("received.ack.real") + Text(": \(message.realACK ? "✔️" : "")")
Text("Received Ack") + Text(": \(message.receivedACK ? "✔️" : "")")
Text("Recipient Ack") + Text(": \(message.realACK ? "✔️" : "")")
}
} else if isCurrentUser && message.ackError == 0 {
// Empty Error

View file

@ -50,7 +50,7 @@ struct Messages: View {
}
NavigationLink(value: MessagesNavigationState.directMessages()) {
Label {
Text("direct.messages")
Text("Direct Messages")
.badge(unreadDirectMessages)
.font(.title2)
.padding()

View file

@ -194,7 +194,7 @@ struct UserList: View {
}
}
.listStyle(.plain)
.navigationTitle(String.localizedStringWithFormat("contacts %@".localized, String(users.count == 0 ? 0 : users.count)))
.navigationTitle(String.localizedStringWithFormat("Contacts (%@)".localized, String(users.count == 0 ? 0 : users.count)))
.sheet(isPresented: $editingFilters) {
NodeListFilter(filterTitle: "Contact Filters", viaLora: $viaLora, viaMqtt: $viaMqtt, isOnline: $isOnline, isPkiEncrypted: $isPkiEncrypted, isFavorite: $isFavorite, isIgnored: $isIgnored, isEnvironment: $isEnvironment, distanceFilter: $distanceFilter, maximumDistance: $maxDistance, hopsAway: $hopsAway, roleFilter: $roleFilter, deviceRoles: $deviceRoles)
}

View file

@ -118,7 +118,7 @@ struct DetectionSensorLog: View {
.padding(.bottom)
.padding(.trailing)
}
.navigationTitle("detection.sensor.log")
.navigationTitle("Detection Sensor Log")
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(trailing:
ZStack {
@ -128,7 +128,7 @@ struct DetectionSensorLog: View {
isPresented: $isExporting,
document: CsvDocument(emptyCsv: exportString),
contentType: .commaSeparatedText,
defaultFilename: String("\(node.user?.longName ?? "Node") \("detection.sensor.log".localized)"),
defaultFilename: String("\(node.user?.longName ?? "Node") \("Detection Sensor Log".localized)"),
onCompletion: { result in
switch result {
case .success:

View file

@ -209,7 +209,7 @@ struct DeviceMetricsLog: View {
isPresented: $isPresentingClearLogConfirm,
titleVisibility: .visible
) {
Button("device.metrics.delete", role: .destructive) {
Button("Delete all device metrics?", role: .destructive) {
if clearTelemetry(destNum: node.num, metricsType: 0, context: context) {
Logger.data.notice("Cleared Device Metrics for \(node.num, privacy: .public)")
} else {
@ -240,7 +240,7 @@ struct DeviceMetricsLog: View {
ContentUnavailableView("No Device Metrics", systemImage: "slash.circle")
}
}
.navigationTitle("device.metrics.log")
.navigationTitle("Device Metrics Log")
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(trailing:
ZStack {
@ -250,7 +250,7 @@ struct DeviceMetricsLog: View {
isPresented: $isExporting,
document: CsvDocument(emptyCsv: exportString),
contentType: .commaSeparatedText,
defaultFilename: String("\(node.user?.longName ?? "Node") \("device.metrics.log".localized)"),
defaultFilename: String("\(node.user?.longName ?? "Node") \("Device Metrics Log".localized)"),
onCompletion: { result in
switch result {
case .success:

View file

@ -499,14 +499,14 @@ struct NodeDetail: View {
showingRebootConfirm = true
} label: {
Label(
"reboot",
"Reboot",
systemImage: "arrow.triangle.2.circlepath"
)
}.confirmationDialog(
"Are you sure?",
isPresented: $showingRebootConfirm
) {
Button("reboot.node", role: .destructive) {
Button("Reboot node?", role: .destructive) {
if !bleManager.sendReboot(
fromUser: connectedNode.user!,
toUser: node.user!,

View file

@ -75,7 +75,7 @@ struct NodeListItem: View {
if connected {
IconAndText(systemName: "antenna.radiowaves.left.and.right.circle.fill",
imageColor: .green,
text: "connected".localized)
text: "Connected".localized)
}
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",

View file

@ -192,7 +192,7 @@ struct NodeList: View {
.searchable(text: $searchText, placement: .automatic, prompt: "Find a node")
.disableAutocorrection(true)
.scrollDismissesKeyboard(.immediately)
.navigationTitle(String.localizedStringWithFormat("nodes %@".localized, String(nodes.count)))
.navigationTitle(String.localizedStringWithFormat("Nodes (%@)".localized, String(nodes.count)))
.listStyle(.plain)
.alert(
"Position Exchange Requested",
@ -272,7 +272,7 @@ struct NodeList: View {
)
}
} else {
ContentUnavailableView("select.node", systemImage: "flipphone")
ContentUnavailableView("Select Node", systemImage: "flipphone")
}
} detail: {
ContentUnavailableView("", systemImage: "line.3.horizontal")

View file

@ -44,7 +44,7 @@ struct PaxCounterLog: View {
y: .value("y", (point.wifi + point.ble))
)
}
.accessibilityLabel("paxcounter.total")
.accessibilityLabel("Total PAX")
.accessibilityValue("X: \(point.time!), Y: \(point.wifi + point.ble)")
.foregroundStyle(paxChartColor)
.interpolationMethod(.cardinal)
@ -55,7 +55,7 @@ struct PaxCounterLog: View {
y: .value("y", point.wifi)
)
}
.accessibilityLabel("paxcounter.wifi")
.accessibilityLabel("WiFi")
.accessibilityValue("X: \(point.time!), Y: \(point.wifi)")
.foregroundStyle(wifiChartColor)
@ -65,7 +65,7 @@ struct PaxCounterLog: View {
y: .value("y", point.ble)
)
}
.accessibilityLabel("paxcounter.ble")
.accessibilityLabel("BLE")
.accessibilityValue("X: \(point.time!), Y: \(point.ble)")
.foregroundStyle(bleChartColor)
}
@ -76,9 +76,9 @@ struct PaxCounterLog: View {
.chartXAxis(.automatic)
.chartYScale(domain: 0...maxValue)
.chartForegroundStyleScale([
"paxcounter.ble".localized: .blue,
"paxcounter.wifi".localized: .orange,
"paxcounter.total".localized: .green
"BLE".localized: .blue,
"WiFi".localized: .orange,
"Total PAX".localized: .green
])
.chartLegend(position: .automatic, alignment: .bottom)
}
@ -89,13 +89,13 @@ struct PaxCounterLog: View {
if UIScreen.main.bounds.size.width > 768 && (UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac) {
// Add a table for mac and ipad
Table(pax) {
TableColumn("paxcounter.ble") { pc in
TableColumn("BLE") { pc in
Text("\(pc.ble)")
}
TableColumn("paxcounter.wifi") { pc in
TableColumn("WiFi") { pc in
Text("\(pc.wifi)")
}
TableColumn("paxcounter.total") { pc in
TableColumn("Total PAX") { pc in
Text("\(pc.wifi + pc.ble)")
}
TableColumn("Uptime") { pc in
@ -120,10 +120,10 @@ struct PaxCounterLog: View {
]
LazyVGrid(columns: columns, alignment: .leading, spacing: 1) {
GridRow {
Text("paxcounter.ble")
Text("BLE")
.font(.caption)
.fontWeight(.bold)
Text("paxcounter.wifi")
Text("WiFi")
.font(.caption)
.fontWeight(.bold)
Text("Total")
@ -174,7 +174,7 @@ struct PaxCounterLog: View {
isPresented: $isPresentingClearLogConfirm,
titleVisibility: .visible
) {
Button("paxcounter.delete", role: .destructive) {
Button("Delete all pax data?", role: .destructive) {
if clearPax(destNum: node.num, context: context) {
Logger.services.info("Cleared Pax Counter for \(node.num, privacy: .public)")
} else {
@ -196,10 +196,10 @@ struct PaxCounterLog: View {
.padding(.trailing)
}
} else {
ContentUnavailableView("paxcounter.content.unavailable", systemImage: "slash.circle")
ContentUnavailableView("No PAX Counter Logs", systemImage: "slash.circle")
}
}
.navigationTitle("paxcounter.log")
.navigationTitle("PAX Counter Log")
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(trailing:
ZStack {

View file

@ -282,7 +282,7 @@ struct PowerMetricsLog: View {
isPresented: $isExporting,
document: CsvDocument(emptyCsv: exportString),
contentType: .commaSeparatedText,
defaultFilename: String("\(node.user?.longName ?? "Node") \("power.metrics.log".localized)"),
defaultFilename: String("\(node.user?.longName ?? "Node") \("Power Metrics Log".localized)"),
onCompletion: { result in
switch result {
case .success:

View file

@ -48,7 +48,7 @@ struct AboutMeshtastic: View {
}
.font(.title2)
Text("Version: \(Bundle.main.appVersionLong) (\(Bundle.main.appBuild)) ")
Text("Version: \(Bundle.main.appVersionLong) (\(Bundle.main.appBuild))")
}
Section(header: Text("Project information")) {

View file

@ -21,7 +21,7 @@ struct AppData: View {
VStack {
Section(header: Text("phone.gps")) {
Section(header: Text("Phone GPS")) {
GPSStatus()
}
Divider()

View file

@ -75,11 +75,11 @@ struct AppLog: View {
}
} else {
Table(logs, selection: $selection, sortOrder: $sortOrder) {
TableColumn("log.time") { value in
TableColumn("Time") { value in
Text(value.date.formatted(dateFormatStyle))
}
.width(min: 125, max: 150)
TableColumn("log.level") { value in
TableColumn("Level") { value in
Text(value.level.description)
.foregroundStyle(value.level.color)
}

View file

@ -379,6 +379,6 @@ enum PositionPrecision: Int, CaseIterable, Identifiable {
var description: String {
let distanceFormatter = MKDistanceFormatter()
return String.localizedStringWithFormat("position.precision %@".localized, String(distanceFormatter.string(fromDistance: precisionMeters)))
return String.localizedStringWithFormat("Within %@".localized, String(distanceFormatter.string(fromDistance: precisionMeters)))
}
}

View file

@ -247,7 +247,7 @@ struct DeviceConfig: View {
}
Spacer()
}
.navigationTitle("device.config")
.navigationTitle("Device Config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(
@ -310,6 +310,9 @@ struct DeviceConfig: View {
}
}
func setDeviceValues() {
if node?.deviceConfig?.role ?? 0 == 3 {
node?.deviceConfig?.role = 1
}
self.deviceRole = Int(node?.deviceConfig?.role ?? 0)
self.buttonGPIO = Int(node?.deviceConfig?.buttonGpio ?? 0)
self.buzzerGPIO = Int(node?.deviceConfig?.buzzerGpio ?? 0)

View file

@ -228,7 +228,7 @@ struct LoRaConfig: View {
}
}
}
.navigationTitle("lora.config")
.navigationTitle("LoRa Config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(
@ -304,6 +304,9 @@ struct LoRaConfig: View {
}
}
func setLoRaValues() {
if node?.loRaConfig?.modemPreset ?? 0 == 2 {
node?.loRaConfig?.modemPreset = 0
}
self.hopLimit = Int(node?.loRaConfig?.hopLimit ?? 3)
self.region = Int(node?.loRaConfig?.regionCode ?? 0)
self.usePreset = node?.loRaConfig?.usePreset ?? true

View file

@ -130,7 +130,7 @@ struct DetectionSensorConfig: View {
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
}
Section(header: Text("update.interval")) {
Section(header: Text("Update Interval")) {
Picker("Minimum time between detection broadcasts", selection: $minimumBroadcastSecs) {
ForEach(UpdateIntervals.allCases) { ui in
Text(ui.description).tag(ui.rawValue)
@ -181,7 +181,7 @@ struct DetectionSensorConfig: View {
}
}
}
.navigationTitle("detection.sensor.config")
.navigationTitle("Detection Sensor Config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(

View file

@ -189,7 +189,7 @@ struct ExternalNotificationConfig: View {
}
}
}
.navigationTitle("external.notification.config")
.navigationTitle("External Notification Config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(

View file

@ -60,7 +60,7 @@ struct MQTTConfig: View {
Toggle(isOn: $proxyToClientEnabled) {
Label("mqtt.clientproxy", systemImage: "iphone.radiowaves.left.and.right")
Label("MQTT Client Proxy", systemImage: "iphone.radiowaves.left.and.right")
Text("Utilizes the network connection on your phone to connect to MQTT.")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
@ -340,7 +340,7 @@ struct MQTTConfig: View {
if newMapPublishIntervalSecs != node?.mqttConfig?.mapPublishIntervalSecs ?? -1 { hasChanges = true }
}
}
.navigationTitle("mqtt.config")
.navigationTitle("MQTT Config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(

View file

@ -41,7 +41,7 @@ struct PaxCounterConfig: View {
}
.pickerStyle(DefaultPickerStyle())
.listRowSeparator(.hidden)
Text("config.module.paxcounter.updateinterval.description")
Text("How often we can send a message to the mesh when people are detected.")
.foregroundColor(.gray)
.font(.callout)
}
@ -50,7 +50,7 @@ struct PaxCounterConfig: View {
}
}
.disabled(self.bleManager.connectedPeripheral == nil || node?.powerConfig == nil)
.navigationTitle("config.module.paxcounter.title")
.navigationTitle("PAX Counter Config")
.navigationBarItems(trailing: ZStack {
ConnectedDevice(
bluetoothOn: bleManager.isSwitchedOn,

View file

@ -71,7 +71,7 @@ struct RangeTestConfig: View {
}
}
}
.navigationTitle("range.test.config")
.navigationTitle("Range Test Config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(

View file

@ -22,12 +22,12 @@ struct RtttlConfig: View {
var body: some View {
VStack {
Form {
ConfigHeader(title: "ringtone", config: \.rtttlConfig, node: node, onAppear: setRtttLConfigValue)
ConfigHeader(title: "Ringtone", config: \.rtttlConfig, node: node, onAppear: setRtttLConfigValue)
Section(header: Text("Options")) {
HStack {
Label("ringtone", systemImage: "music.quarternote.3")
TextField("config.ringtone.label", text: $ringtone, axis: .vertical)
Label("Ringtone", systemImage: "music.quarternote.3")
TextField("Ringtone Transfer Language", text: $ringtone, axis: .vertical)
.foregroundColor(.gray)
.autocapitalization(.none)
.disableAutocorrection(true)
@ -43,7 +43,7 @@ struct RtttlConfig: View {
}
.keyboardType(.default)
.listRowSeparator(.hidden)
Text("config.ringtone.description")
Text("Ringtone Transfer Language(RTTTL) Ringtone String used by supported buzzers in external notifications.")
.foregroundColor(.gray)
.font(.callout)
}
@ -62,7 +62,7 @@ struct RtttlConfig: View {
}
}
}
.navigationTitle("config.ringtone.title")
.navigationTitle("Ringtone Config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(

View file

@ -126,7 +126,7 @@ struct SerialConfig: View {
}
}
}
.navigationTitle("serial.config")
.navigationTitle("Serial Config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(

View file

@ -46,7 +46,7 @@ struct StoreForwardConfig: View {
if enabled {
Section(header: Text("Settings")) {
Toggle(isOn: $heartbeat) {
Label("storeforward.heartbeat", systemImage: "waveform.path.ecg")
Label("Send Heartbeat", systemImage: "waveform.path.ecg")
Text("Send a heartbeat to advertise the server's presence.")
}
Picker("Number of records", selection: $records) {

View file

@ -32,7 +32,7 @@ struct TelemetryConfig: View {
Form {
ConfigHeader(title: "Telemetry", config: \.telemetryConfig, node: node, onAppear: setTelemetryValues)
Section(header: Text("update.interval")) {
Section(header: Text("Update Interval")) {
Picker("Device Metrics", selection: $deviceUpdateInterval ) {
ForEach(UpdateIntervals.allCases) { ui in
if ui.rawValue >= 900 {
@ -124,7 +124,7 @@ struct TelemetryConfig: View {
}
}
}
.navigationTitle("telemetry.config")
.navigationTitle("Telemetry Config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(

View file

@ -42,8 +42,8 @@ struct NetworkConfig: View {
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
HStack {
Label("ssid", systemImage: "network")
TextField("ssid", text: $wifiSsid)
Label("SSID", systemImage: "network")
TextField("SSID", text: $wifiSsid)
.foregroundColor(.gray)
.autocapitalization(.none)
.disableAutocorrection(true)
@ -123,7 +123,7 @@ struct NetworkConfig: View {
}
}
}
.navigationTitle("network.config")
.navigationTitle("Network Config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(

View file

@ -394,7 +394,7 @@ struct PositionConfig: View {
}
saveButton
}
.navigationTitle("position.config")
.navigationTitle("Position Config")
.navigationBarItems(
trailing: ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: bleManager.connectedPeripheral?.shortName ?? "?")

View file

@ -27,18 +27,18 @@ struct PowerConfig: View {
var body: some View {
Form {
ConfigHeader(title: "config.power.title", config: \.powerConfig, node: node, onAppear: setPowerValues)
ConfigHeader(title: "Power Config", config: \.powerConfig, node: node, onAppear: setPowerValues)
Section {
if (currentDevice?.architecture == .esp32 || currentDevice?.architecture == .esp32S3) || (currentDevice?.architecture == .nrf52840 && (node?.deviceConfig?.role ?? 0 == 5 || node?.deviceConfig?.role ?? 0 == 6)) {
Toggle(isOn: $isPowerSaving) {
Label("config.power.saving", systemImage: "bolt")
Text("config.power.saving.description")
Label("Power Saving", systemImage: "bolt")
Text("Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio. Don't use this setting if you want to use your device with the phone apps or are using a device without a user button.")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
}
Toggle(isOn: $shutdownOnPowerLoss) {
Label("config.power.shutdown.on.power.loss", systemImage: "power")
Label("Shutdown on Power Loss", systemImage: "power")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
if shutdownOnPowerLoss {
@ -55,15 +55,15 @@ struct PowerConfig: View {
if currentDevice?.architecture == .esp32 || currentDevice?.architecture == .esp32S3 {
Section {
Toggle(isOn: $adcOverride) {
Text("config.power.adc.override")
Text("ADC Override")
}
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
if adcOverride {
HStack {
Text("config.power.adc.multiplier")
Text("Multiplier")
Spacer()
FloatField(title: "config.power.adc.multiplier", number: $adcMultiplier) {
FloatField(title: "Multiplier", number: $adcMultiplier) {
(2.0 ... 6.0).contains($0)
}
.focused($isFocused)
@ -71,7 +71,7 @@ struct PowerConfig: View {
}
}
} header: {
Text("config.power.section.battery")
Text("Battery")
}
// Section {
// Picker("config.power.wait.bluetooth.secs", selection: $waitBluetoothSecs) {
@ -101,7 +101,7 @@ struct PowerConfig: View {
}
}
.disabled(self.bleManager.connectedPeripheral == nil || node?.powerConfig == nil)
.navigationTitle("config.power.title")
.navigationTitle("Power Config")
.navigationBarItems(trailing: ZStack {
ConnectedDevice(
bluetoothOn: bleManager.isSwitchedOn,

View file

@ -25,12 +25,12 @@ struct SaveConfigButton: View {
titleVisibility: .visible
) {
let nodeName = node?.user?.longName ?? "Unknown".localized
let buttonText = String.localizedStringWithFormat("save.config %@".localized, nodeName)
let buttonText = String.localizedStringWithFormat("Save Config for %@".localized, nodeName)
Button(buttonText) {
onConfirmation()
}
} message: {
Text("config.save.confirm")
Text("After config values save the node will reboot.")
}
}
}

View file

@ -38,7 +38,7 @@ struct LogDetail: View {
/// Time
Label {
HStack {
Text("log.time".localized + ":")
Text("Time".localized + ":")
.font(idiom == .phone ? .caption : .title)
.frame(width: idiom == .phone ? 115 : 190, alignment: .trailing)
Text(log.date.formatted(dateFormatStyle))
@ -56,7 +56,7 @@ struct LogDetail: View {
/// Subsystem
Label {
HStack {
Text("log.subsystem".localized + ":")
Text("Subsystem".localized + ":")
.font(idiom == .phone ? .caption : .title)
.frame(width: idiom == .phone ? 115 : 190, alignment: .trailing)
Text(log.subsystem)
@ -73,7 +73,7 @@ struct LogDetail: View {
/// Process
Label {
HStack {
Text("log.process".localized + ":")
Text("Process".localized + ":")
.font(idiom == .phone ? .caption : .title)
.frame(width: idiom == .phone ? 115 : 190, alignment: .trailing)
Text(log.process)
@ -90,7 +90,7 @@ struct LogDetail: View {
/// Level
Label {
HStack {
Text("log.level".localized + ":")
Text("Level".localized + ":")
.font(idiom == .phone ? .caption : .title)
.frame(width: idiom == .phone ? 115 : 190, alignment: .trailing)
Text(log.level.description)

View file

@ -191,7 +191,7 @@ struct RouteRecorder: View {
Logger.data.error("Error Saving RouteEntity from the Route Recorder \(nsError, privacy: .public)")
}
} label: {
Label("start", systemImage: "play")
Label("Start", systemImage: "play")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)
@ -204,7 +204,7 @@ struct RouteRecorder: View {
locationsHandler.isRecording = false
locationsHandler.isRecordingPaused = true
} label: {
Label("pause", systemImage: "pause")
Label("Pause", systemImage: "pause")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)
@ -216,7 +216,7 @@ struct RouteRecorder: View {
locationsHandler.isRecording = true
locationsHandler.isRecordingPaused = false
} label: {
Label("resume", systemImage: "playpause")
Label("Resume", systemImage: "playpause")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)

View file

@ -44,7 +44,7 @@ struct Settings: View {
// MARK: Views
var radioConfigurationSection: some View {
Section("radio.configuration") {
Section("Radio Configuration") {
let node = nodes.first(where: { $0.num == preferredNodeNum })
if let node,
let loRaConfig = node.loRaConfig,
@ -69,7 +69,7 @@ struct Settings: View {
NavigationLink(value: SettingsNavigationState.lora) {
Label {
Text("lora")
Text("LoRa")
} icon: {
Image(systemName: "dot.radiowaves.left.and.right")
.rotationEffect(.degrees(-90))
@ -95,7 +95,7 @@ struct Settings: View {
NavigationLink(value: SettingsNavigationState.shareQRCode) {
Label {
Text("share.channels")
Text("Share QR Code")
} icon: {
Image(systemName: "qrcode")
}
@ -124,7 +124,7 @@ struct Settings: View {
NavigationLink(value: SettingsNavigationState.device) {
Label {
Text("device")
Text("Device")
} icon: {
Image(systemName: "flipphone")
}
@ -140,7 +140,7 @@ struct Settings: View {
NavigationLink(value: SettingsNavigationState.network) {
Label {
Text("network")
Text("Network")
} icon: {
Image(systemName: "network")
}
@ -189,7 +189,7 @@ struct Settings: View {
if isModuleSupported(.detectionsensorConfig) {
NavigationLink(value: SettingsNavigationState.detectionSensor) {
Label {
Text("detection.sensor")
Text("Detection Sensor")
} icon: {
Image(systemName: "sensor")
}
@ -199,7 +199,7 @@ struct Settings: View {
if isModuleSupported(.extnotifConfig) {
NavigationLink(value: SettingsNavigationState.externalNotification) {
Label {
Text("external.notification")
Text("External Notification")
} icon: {
Image(systemName: "megaphone")
}
@ -219,7 +219,7 @@ struct Settings: View {
if isModuleSupported(.rangetestConfig) {
NavigationLink(value: SettingsNavigationState.rangeTest) {
Label {
Text("range.test")
Text("Range Test")
} icon: {
Image(systemName: "point.3.connected.trianglepath.dotted")
}
@ -269,7 +269,7 @@ struct Settings: View {
if isModuleSupported(.telemetryConfig) {
NavigationLink(value: SettingsNavigationState.telemetry) {
Label {
Text("telemetry")
Text("Telemetry")
} icon: {
Image(systemName: "chart.xyaxis.line")
}
@ -286,7 +286,7 @@ struct Settings: View {
Text("This node does not support any configurable modules.")
}
} header: {
Text("module.configuration")
Text("Module Configuration")
} footer: {
if moduleOverride {
Text("Currently showing modules that may not be supported by this node.")
@ -295,7 +295,7 @@ struct Settings: View {
}
var loggingSection: some View {
Section(header: Text("logging")) {
Section(header: Text("Logging")) {
NavigationLink(value: SettingsNavigationState.debugLogs) {
Label {
Text("Logs")

View file

@ -226,7 +226,7 @@ struct ShareChannels: View {
}
}
}
.navigationTitle("generate.qr.code")
.navigationTitle("Generate QR Code")
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(trailing:
ZStack {

View file

@ -186,7 +186,7 @@ struct UserConfig: View {
}
}
} message: {
Text("config.save.confirm")
Text("After config values save the node will reboot.")
}
}
Spacer()