mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
* More strings
* Add duty cycle error * Don't log local telemetry in the mesh log
This commit is contained in:
parent
5da522b911
commit
eedbef57fb
21 changed files with 256 additions and 195 deletions
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Copyright(c) Garth Vander Houwen 8/19/22.
|
||||
//
|
||||
import Foundation
|
||||
|
||||
enum BluetoothModes: Int, CaseIterable, Identifiable {
|
||||
|
||||
|
|
@ -16,11 +17,11 @@ enum BluetoothModes: Int, CaseIterable, Identifiable {
|
|||
get {
|
||||
switch self {
|
||||
case .randomPin:
|
||||
return "Random PIN"
|
||||
return NSLocalizedString("bluetooth.mode.randompin", comment: "Random PIN")
|
||||
case .fixedPin:
|
||||
return "Fixed PIN"
|
||||
return NSLocalizedString("bluetooth.mode.fixedpin", comment: "Fixed PIN")
|
||||
case .noPin:
|
||||
return "No PIN (Just Works)"
|
||||
return NSLocalizedString("bluetooth.mode.nopin", comment: "No PIN (Just Works)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Copyright(c) Garth Vander Houwen 9/10/22.
|
||||
//
|
||||
import Foundation
|
||||
|
||||
// Default of 0 is unset
|
||||
enum ConfigPresets : Int, CaseIterable, Identifiable {
|
||||
|
|
@ -18,11 +19,11 @@ enum ConfigPresets : Int, CaseIterable, Identifiable {
|
|||
switch self {
|
||||
|
||||
case .unset:
|
||||
return "Manual Configuration"
|
||||
return NSLocalizedString("canned.messages.preset.manual", comment: "Manual Configuration")
|
||||
case .rakRotaryEncoder:
|
||||
return "RAK Rotary Encoder Module"
|
||||
return NSLocalizedString("canned.messages.preset.rakrotary", comment: "RAK Rotary Encoder Module")
|
||||
case .cardKB:
|
||||
return "M5 Stack Card KB / RAK Keypad"
|
||||
return NSLocalizedString("canned.messages.preset.cardkb", comment: "M5 Stack Card KB / RAK Keypad")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -46,21 +47,21 @@ enum InputEventChars: Int, CaseIterable, Identifiable {
|
|||
switch self {
|
||||
|
||||
case .none:
|
||||
return "None"
|
||||
return NSLocalizedString("inputevent.none", comment: "None")
|
||||
case .up:
|
||||
return "Up"
|
||||
return NSLocalizedString("inputevent.up", comment: "Up")
|
||||
case .down:
|
||||
return "Down"
|
||||
return NSLocalizedString("inputevent.down", comment: "Down")
|
||||
case .left:
|
||||
return "Left"
|
||||
return NSLocalizedString("inputevent.left", comment: "Left")
|
||||
case .right:
|
||||
return "Right"
|
||||
return NSLocalizedString("inputevent.right", comment: "Right")
|
||||
case .select:
|
||||
return "Select"
|
||||
return NSLocalizedString("inputevent.select", comment: "Select")
|
||||
case .back:
|
||||
return "Back"
|
||||
return NSLocalizedString("inputevent.back", comment: "Back")
|
||||
case .cancel:
|
||||
return "Cancel"
|
||||
return NSLocalizedString("inputevent.cancel", comment: "Cancel")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Copyright(c) Garth Vander Houwen 9/21/22.
|
||||
//
|
||||
import Foundation
|
||||
|
||||
// Default of 0 is Client
|
||||
enum ChannelRoles: Int, CaseIterable, Identifiable {
|
||||
|
|
@ -18,11 +19,11 @@ enum ChannelRoles: Int, CaseIterable, Identifiable {
|
|||
switch self {
|
||||
|
||||
case .disabled:
|
||||
return "Disabled"
|
||||
return NSLocalizedString("channel.role.disabled", comment: "Disabled")
|
||||
case .primary:
|
||||
return "Primary"
|
||||
return NSLocalizedString("channel.role.primary", comment: "Primary")
|
||||
case .secondary:
|
||||
return "Secondary"
|
||||
return NSLocalizedString("channel.role.secondary", comment: "Secondary")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ enum DeviceRoles: Int, CaseIterable, Identifiable {
|
|||
switch self {
|
||||
|
||||
case .client:
|
||||
return "Client (default) - App connected client."
|
||||
return NSLocalizedString("device.role.client", comment: "Client (default) - App connected client.")
|
||||
case .clientMute:
|
||||
return "Client Mute - Same as a client except packets will not hop over this node, does not contribute to routing packets for mesh."
|
||||
return NSLocalizedString("device.role.clientmute", comment: "Client Mute - Same as a client except packets will not hop over this node, does not contribute to routing packets for mesh.")
|
||||
case .router:
|
||||
return "Router - Mesh packets will prefer to be routed over this node. This node will not be used by client apps. The wifi/ble radios and the oled screen will be put to sleep."
|
||||
return NSLocalizedString("device.role.router", comment: "Router - Mesh packets will prefer to be routed over this node. This node will not be used by client apps. The wifi/ble radios and the oled screen will be put to sleep.")
|
||||
case .routerClient:
|
||||
return "Router Client - Mesh packets will prefer to be routed over this node. The Router Client can be used as both a Router and an app connected Client."
|
||||
return NSLocalizedString("device.role.routerclient", comment: "Router Client - Mesh packets will prefer to be routed over this node. The Router Client can be used as both a Router and an app connected Client.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,23 +49,24 @@ enum ScreenOnIntervals: Int, CaseIterable, Identifiable {
|
|||
get {
|
||||
switch self {
|
||||
case .oneMinute:
|
||||
return "One Minute"
|
||||
return NSLocalizedString("interval.one.minute", comment: "One Minute")
|
||||
case .fiveMinutes:
|
||||
return "Five Minutes"
|
||||
return NSLocalizedString("interval.five.minutes", comment: "Five Minutes")
|
||||
case .tenMinutes:
|
||||
return "Ten Minutes"
|
||||
return NSLocalizedString("interval.ten.minutes", comment: "Ten Minutes")
|
||||
case .fifteenMinutes:
|
||||
return "Fifteen Minutes"
|
||||
return NSLocalizedString("interval.fifteen.minutes", comment: "Fifteen Minutes")
|
||||
case .thirtyMinutes:
|
||||
return "Thirty Minutes"
|
||||
return NSLocalizedString("interval.thirty.minutes", comment: "Thirty Minutes")
|
||||
case .oneHour:
|
||||
return "One Hour"
|
||||
return NSLocalizedString("interval.one.hour", comment: "One Hour")
|
||||
case .max:
|
||||
return "Always On"
|
||||
return NSLocalizedString("always.on", comment: "Always On")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default of 0 is off
|
||||
enum ScreenCarouselIntervals: Int, CaseIterable, Identifiable {
|
||||
|
||||
|
|
@ -81,17 +82,17 @@ enum ScreenCarouselIntervals: Int, CaseIterable, Identifiable {
|
|||
get {
|
||||
switch self {
|
||||
case .off:
|
||||
return "Off"
|
||||
return NSLocalizedString("off", comment: "Off")
|
||||
case .thirtySeconds:
|
||||
return "Thirty Seconds"
|
||||
return NSLocalizedString("interval.thirty.seconds", comment: "Thirty Seconds")
|
||||
case .oneMinute:
|
||||
return "One Minute"
|
||||
return NSLocalizedString("interval.one.minute", comment: "One Minute")
|
||||
case .fiveMinutes:
|
||||
return "Five Minutes"
|
||||
return NSLocalizedString("interval.five.minutes", comment: "Five Minutes")
|
||||
case .tenMinutes:
|
||||
return "Ten Minutes"
|
||||
return NSLocalizedString("interval.ten.minutes", comment: "Ten Minutes")
|
||||
case .fifteenMinutes:
|
||||
return "Fifteen Minutes"
|
||||
return NSLocalizedString("interval.fifteen.minutes", comment: "Fifteen Minutes")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -109,7 +110,7 @@ enum OledTypes: Int, CaseIterable, Identifiable {
|
|||
get {
|
||||
switch self {
|
||||
case .auto:
|
||||
return "Automatic Detection"
|
||||
return NSLocalizedString("automatic.detection", comment: "Automatic Detection")
|
||||
case .ssd1306:
|
||||
return "SSD 1306"
|
||||
case .sh1106:
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Copyright(c) Garth Vander Houwen 9/30/22.
|
||||
//
|
||||
import Foundation
|
||||
|
||||
enum BubblePosition {
|
||||
case left
|
||||
|
|
@ -45,19 +46,19 @@ enum Tapbacks: Int, CaseIterable, Identifiable {
|
|||
get {
|
||||
switch self {
|
||||
case .heart:
|
||||
return "Heart"
|
||||
return NSLocalizedString("tapback.heart", comment: "Heart")
|
||||
case .thumbsUp:
|
||||
return "Thumbs Up"
|
||||
return NSLocalizedString("tapback.thumbsup", comment: "Thumbs Up")
|
||||
case .thumbsDown:
|
||||
return "Thumbs Down"
|
||||
return NSLocalizedString("tapback.thumbsdown", comment: "Thumbs Down")
|
||||
case .haHa:
|
||||
return "HaHa"
|
||||
return NSLocalizedString("tapback.haha", comment: "HaHa")
|
||||
case .exclamation:
|
||||
return "Exclamation Mark"
|
||||
return NSLocalizedString("tapback.exclamation", comment: "Exclamation Mark")
|
||||
case .question:
|
||||
return "Question Mark"
|
||||
return NSLocalizedString("tapback.question", comment: "Question Mark")
|
||||
case .poop:
|
||||
return "Poop"
|
||||
return NSLocalizedString("tapback.poop", comment: "Poop")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,27 +27,27 @@ enum PositionBroadcastIntervals: Int, CaseIterable, Identifiable {
|
|||
switch self {
|
||||
|
||||
case .fifteenSeconds:
|
||||
return "Fifteen Seconds"
|
||||
return NSLocalizedString("interval.fifteen.seconds", comment: "Fifteen Seconds")
|
||||
case .thirtySeconds:
|
||||
return "Thirty Seconds"
|
||||
return NSLocalizedString("interval.thirty.seconds", comment: "Thirty Seconds")
|
||||
case .oneMinute:
|
||||
return "One Minute"
|
||||
return NSLocalizedString("interval.one.minute", comment: "One Minute")
|
||||
case .fiveMinutes:
|
||||
return "Five Minutes"
|
||||
return NSLocalizedString("interval.five.minutes", comment: "Five Minutes")
|
||||
case .tenMinutes:
|
||||
return "Ten Minutes"
|
||||
return NSLocalizedString("interval.ten.minutes", comment: "Ten Minutes")
|
||||
case .fifteenMinutes:
|
||||
return "Fifteen Minutes"
|
||||
return NSLocalizedString("interval.fifteen.minutes", comment: "Fifteen Minutes")
|
||||
case .thirtyMinutes:
|
||||
return "Thirty Minutes"
|
||||
return NSLocalizedString("interval.thirty.minutes", comment: "Thirty Minutes")
|
||||
case .oneHour:
|
||||
return "One Hour"
|
||||
return NSLocalizedString("interval.one.hour", comment: "One Hour")
|
||||
case .sixHours:
|
||||
return "Six Hours"
|
||||
return NSLocalizedString("interval.six.hours", comment: "Six Hours")
|
||||
case .twelveHours:
|
||||
return "Twelve Hours"
|
||||
return NSLocalizedString("interval.twelve.hours", comment: "Twelve Hours")
|
||||
case .twentyFourHours:
|
||||
return "Twenty Four Hours"
|
||||
return NSLocalizedString("interval.twentyfour.hours", comment: "Twenty Four Hours")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -67,17 +67,17 @@ enum GpsFormats: Int, CaseIterable, Identifiable {
|
|||
get {
|
||||
switch self {
|
||||
case .gpsFormatDec:
|
||||
return "Decimal Degrees Format"
|
||||
return NSLocalizedString("gpsformat.dec", comment: "Decimal Degrees Format")
|
||||
case .gpsFormatDms:
|
||||
return "Degrees Minutes Seconds"
|
||||
return NSLocalizedString("gpsformat.dms", comment: "Degrees Minutes Seconds")
|
||||
case .gpsFormatUtm:
|
||||
return "Universal Transverse Mercator"
|
||||
return NSLocalizedString("gpsformat.utm", comment: "Universal Transverse Mercator")
|
||||
case .gpsFormatMgrs:
|
||||
return "Military Grid Reference System"
|
||||
return NSLocalizedString("gpsformat.mgrs", comment: "Military Grid Reference System")
|
||||
case .gpsFormatOlc:
|
||||
return "Open Location Code (aka Plus Codes)"
|
||||
return NSLocalizedString("gpsformat.olc", comment: "Open Location Code (aka Plus Codes)")
|
||||
case .gpsFormatOsgr:
|
||||
return "Ordnance Survey Grid Reference"
|
||||
return NSLocalizedString("gpsformat.osgr", comment: "Ordnance Survey Grid Reference")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -128,39 +128,39 @@ enum GpsUpdateIntervals: Int, CaseIterable, Identifiable {
|
|||
switch self {
|
||||
|
||||
case .fiveSeconds:
|
||||
return "Five Seconds"
|
||||
return NSLocalizedString("interval.five.seconds", comment: "Five Seconds")
|
||||
case .tenSeconds:
|
||||
return "Ten Seconds"
|
||||
return NSLocalizedString("interval.ten.seconds", comment: "Ten Seconds")
|
||||
case .fifteenSeconds:
|
||||
return "Fifteen Seconds"
|
||||
return NSLocalizedString("interval.fifteen.seconds", comment: "Fifteen Seconds")
|
||||
case .twentySeconds:
|
||||
return "Twenty Seconds"
|
||||
return NSLocalizedString("interval.twenty.seconds", comment: "Twenty Seconds")
|
||||
case .twentyFiveSeconds:
|
||||
return "Twenty Five Seconds"
|
||||
return NSLocalizedString("interval.twentyfive.seconds", comment: "Twenty Five Seconds")
|
||||
case .thirtySeconds:
|
||||
return "Thirty Seconds"
|
||||
return NSLocalizedString("interval.thirty.seconds", comment: "Thirty Seconds")
|
||||
case .oneMinute:
|
||||
return "One Minute"
|
||||
return NSLocalizedString("interval.one.minute", comment: "One Minute")
|
||||
case .twoMinutes:
|
||||
return "Two Minutes"
|
||||
return NSLocalizedString("interval.two.minutes", comment: "Two Minutes")
|
||||
case .fiveMinutes:
|
||||
return "Five Minutes"
|
||||
return NSLocalizedString("interval.five.minutes", comment: "Five Minutes")
|
||||
case .tenMinutes:
|
||||
return "Ten Minutes"
|
||||
return NSLocalizedString("interval.ten.minutes", comment: "Ten Minutes")
|
||||
case .fifteenMinutes:
|
||||
return "Fifteen Minutes"
|
||||
return NSLocalizedString("interval.fifteen.minutes", comment: "Fifteen Minutes")
|
||||
case .thirtyMinutes:
|
||||
return "Thirty Minutes"
|
||||
return NSLocalizedString("interval.thirty.minutes", comment: "Thirty Minutes")
|
||||
case .oneHour:
|
||||
return "One Hour"
|
||||
return NSLocalizedString("interval.one.hour", comment: "One Hour")
|
||||
case .sixHours:
|
||||
return "Six Hours"
|
||||
return NSLocalizedString("interval.six.hours", comment: "Six Hours")
|
||||
case .twelveHours:
|
||||
return "Twelve Hours"
|
||||
return NSLocalizedString("interval.twelve.hours", comment: "Twelve Hours")
|
||||
case .twentyFourHours:
|
||||
return "Twenty Four Hours"
|
||||
return NSLocalizedString("interval.twentyfour.hours", comment: "Twenty Four Hours")
|
||||
case .maxInt32:
|
||||
return "On Boot Only"
|
||||
return NSLocalizedString("on.boot", comment: "On Boot Only")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -168,10 +168,7 @@ enum GpsUpdateIntervals: Int, CaseIterable, Identifiable {
|
|||
|
||||
enum GpsAttemptTimes: Int, CaseIterable, Identifiable {
|
||||
|
||||
case oneSecond = 1
|
||||
case twoSeconds = 2
|
||||
case threeSeconds = 3
|
||||
case fourSeconds = 4
|
||||
case fiveSeconds = 5
|
||||
case tenSeconds = 10
|
||||
case fifteenSeconds = 15
|
||||
|
|
@ -179,6 +176,7 @@ enum GpsAttemptTimes: Int, CaseIterable, Identifiable {
|
|||
case twentyFiveSeconds = 25
|
||||
case thirtySeconds = 30
|
||||
case oneMinute = 60
|
||||
case twoMinutes = 120
|
||||
case fiveMinutes = 300
|
||||
|
||||
var id: Int { self.rawValue }
|
||||
|
|
@ -186,30 +184,26 @@ enum GpsAttemptTimes: Int, CaseIterable, Identifiable {
|
|||
get {
|
||||
switch self {
|
||||
|
||||
case .oneSecond:
|
||||
return "One Seconds"
|
||||
case .twoSeconds:
|
||||
return "Two Seconds"
|
||||
case .threeSeconds:
|
||||
return "Three Seconds"
|
||||
case .fourSeconds:
|
||||
return "Four Seconds"
|
||||
return NSLocalizedString("interval.two.seconds", comment: "Two Seconds")
|
||||
case .fiveSeconds:
|
||||
return "Five Seconds"
|
||||
return NSLocalizedString("interval.five.seconds", comment: "Five Seconds")
|
||||
case .tenSeconds:
|
||||
return "Ten Seconds"
|
||||
return NSLocalizedString("interval.ten.seconds", comment: "Ten Seconds")
|
||||
case .fifteenSeconds:
|
||||
return "Fifteen Seconds"
|
||||
return NSLocalizedString("interval.fifteen.seconds", comment: "Fifteen Seconds")
|
||||
case .twentySeconds:
|
||||
return "Twenty Seconds"
|
||||
return NSLocalizedString("interval.twenty.seconds", comment: "Twenty Seconds")
|
||||
case .twentyFiveSeconds:
|
||||
return "Twenty Five Seconds"
|
||||
return NSLocalizedString("interval.twentyfive.seconds", comment: "Twenty Five Seconds")
|
||||
case .thirtySeconds:
|
||||
return "Thirty Seconds"
|
||||
return NSLocalizedString("interval.thirty.seconds", comment: "Thirty Seconds")
|
||||
case .oneMinute:
|
||||
return "One Minute"
|
||||
return NSLocalizedString("interval.one.minute", comment: "One Minute")
|
||||
case .twoMinutes:
|
||||
return NSLocalizedString("interval.two.minutes", comment: "Two Minutes")
|
||||
case .fiveMinutes:
|
||||
return "Five Minutes"
|
||||
return NSLocalizedString("interval.five.minutes", comment: "Five Minutes")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Copyright(c) Garth Vander Houwen 8/4/22.
|
||||
//
|
||||
import Foundation
|
||||
|
||||
enum RoutingError: Int, CaseIterable, Identifiable {
|
||||
|
||||
|
|
@ -16,6 +17,7 @@ enum RoutingError: Int, CaseIterable, Identifiable {
|
|||
case noChannel = 6
|
||||
case tooLarge = 7
|
||||
case noResponse = 8
|
||||
case dutyCycleLimit = 9
|
||||
case badRequest = 32
|
||||
case notAuthorized = 33
|
||||
|
||||
|
|
@ -25,56 +27,29 @@ enum RoutingError: Int, CaseIterable, Identifiable {
|
|||
switch self {
|
||||
|
||||
case .none:
|
||||
return "No Error."
|
||||
return NSLocalizedString("routing.acknowledged", comment: "Acknowledged")
|
||||
case .noRoute:
|
||||
return "No Route"
|
||||
return NSLocalizedString("routing.noroute", comment: "No Route")
|
||||
case .gotNak:
|
||||
return "Received a nak"
|
||||
return NSLocalizedString("routing.gotnak", comment: "Received a negative acknowledgment")
|
||||
case .timeout:
|
||||
return "Timeout"
|
||||
return NSLocalizedString("routing.timeout", comment: "Timeout")
|
||||
case .noInterface:
|
||||
return "No Interface"
|
||||
return NSLocalizedString("routing.nointerface", comment: "No Interface")
|
||||
case .maxRetransmit:
|
||||
return "Max Retransmission Reached"
|
||||
return NSLocalizedString("routing.maxretransmit", comment: "Max Retransmission Reached")
|
||||
case .noChannel:
|
||||
return "No Channel"
|
||||
return NSLocalizedString("routing.nochannel", comment: "No Channel")
|
||||
case .tooLarge:
|
||||
return "The packet is too large"
|
||||
return NSLocalizedString("routing.toolarge", comment: "The packet is too large")
|
||||
case .noResponse:
|
||||
return "No Response"
|
||||
return NSLocalizedString("routing.noresponse", comment: "No Response")
|
||||
case .dutyCycleLimit:
|
||||
return NSLocalizedString("routing.dutycyclelimit", comment: "Regional Duty Cycle Limit Reached")
|
||||
case .badRequest:
|
||||
return "Bad Request"
|
||||
return NSLocalizedString("routing.badRequest", comment: "Bad Request")
|
||||
case .notAuthorized:
|
||||
return "Not Authorized"
|
||||
}
|
||||
}
|
||||
}
|
||||
var description: String {
|
||||
get {
|
||||
switch self {
|
||||
|
||||
case .none:
|
||||
return "This message is not a failure."
|
||||
case .noRoute:
|
||||
return "Our node doesn't have a route to the requested destination anymore."
|
||||
case .gotNak:
|
||||
return "We received a nak while trying to forward on your behalf."
|
||||
case .timeout:
|
||||
return "We timed out while attempting to route this packet."
|
||||
case .noInterface:
|
||||
return "No suitable interface could be found for delivering this packet."
|
||||
case .maxRetransmit:
|
||||
return "We reached the max retransmission count (Hop Limit) and have received no responses."
|
||||
case .noChannel:
|
||||
return "No suitable channel was found for sending this packet (i.e. was requested channel index disabled?)."
|
||||
case .tooLarge:
|
||||
return "The packet was too big for sending (exceeds interface MTU after encoding)."
|
||||
case .noResponse:
|
||||
return "The request had want_response set, the request reached the destination node, but no service on that node wants to send a response (possibly due to bad channel permissions)."
|
||||
case .badRequest:
|
||||
return "The application layer service on the remote node received your request, but considered your request somehow invalid."
|
||||
case .notAuthorized:
|
||||
return "The application layer service on the remote node received your request, but considered your request not authorized (i.e you did not send the request on the required bound channel)."
|
||||
return NSLocalizedString("routing.notauthorized", comment: "Not Authorized")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -100,10 +75,13 @@ enum RoutingError: Int, CaseIterable, Identifiable {
|
|||
return Routing.Error.tooLarge
|
||||
case .noResponse:
|
||||
return Routing.Error.noResponse
|
||||
case .dutyCycleLimit:
|
||||
return Routing.Error.dutyCycleLimit
|
||||
case .badRequest:
|
||||
return Routing.Error.badRequest
|
||||
case .notAuthorized:
|
||||
return Routing.Error.notAuthorized
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
//
|
||||
// Copyright(c) Garth Vander Houwen 9/10/22.
|
||||
//
|
||||
import Foundation
|
||||
|
||||
enum SerialBaudRates: Int, CaseIterable, Identifiable {
|
||||
|
||||
|
|
@ -30,7 +31,7 @@ enum SerialBaudRates: Int, CaseIterable, Identifiable {
|
|||
switch self {
|
||||
|
||||
case .baudDefault:
|
||||
return "Baud Default"
|
||||
return NSLocalizedString("default", comment: "Default")
|
||||
case .baud110:
|
||||
return "110 Baud"
|
||||
case .baud300:
|
||||
|
|
@ -118,15 +119,15 @@ enum SerialModeTypes: Int, CaseIterable, Identifiable {
|
|||
get {
|
||||
switch self {
|
||||
case .default:
|
||||
return "Default"
|
||||
return NSLocalizedString("serial.mode.default", comment: "Default")
|
||||
case .simple:
|
||||
return "Simple"
|
||||
return NSLocalizedString("serial.mode.simple", comment: "Simple")
|
||||
case .proto:
|
||||
return "Protobufs"
|
||||
return NSLocalizedString("serial.mode.proto", comment: "Protobufs")
|
||||
case .txtmsg:
|
||||
return "Text Message"
|
||||
return NSLocalizedString("serial.mode.txtmsg", comment: "Text Message")
|
||||
case .nmea:
|
||||
return "NMEA Positions"
|
||||
return NSLocalizedString("serial.mode.nmea", comment: "NMEA Positions")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -166,20 +167,19 @@ enum SerialTimeoutIntervals: Int, CaseIterable, Identifiable {
|
|||
case .unset:
|
||||
return "Unset"
|
||||
case .oneSecond:
|
||||
return "One Second"
|
||||
return NSLocalizedString("interval.one.second", comment: "One Second")
|
||||
case .fiveSeconds:
|
||||
return "Five Seconds"
|
||||
return NSLocalizedString("interval.five.seconds", comment: "Five Seconds")
|
||||
case .tenSeconds:
|
||||
return "Ten Seconds"
|
||||
return NSLocalizedString("interval.ten.seconds", comment: "Ten Seconds")
|
||||
case .fifteenSeconds:
|
||||
return "Fifteen Seconds"
|
||||
return NSLocalizedString("interval.fifteen.seconds", comment: "Fifteen Seconds")
|
||||
case .thirtySeconds:
|
||||
return "Thirty Seconds"
|
||||
return NSLocalizedString("interval.thirty.seconds", comment: "Thirty Seconds")
|
||||
case .oneMinute:
|
||||
return "One Minute"
|
||||
return NSLocalizedString("interval.one.minute", comment: "One Minute")
|
||||
case .fiveMinutes:
|
||||
return "Five Minutes"
|
||||
|
||||
return NSLocalizedString("interval.five.minutes", comment: "Five Minutes")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ func TelemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin
|
|||
csvString += ", "
|
||||
csvString += String(dm.airUtilTx)
|
||||
csvString += ", "
|
||||
csvString += dm.time?.formattedDate(format: "yyyy-MM-dd HH:mm:ss") ?? "Unknown Age"
|
||||
csvString += dm.time?.formattedDate(format: "yyyy-MM-dd HH:mm:ss") ?? NSLocalizedString("unknown.age", comment: "")
|
||||
}
|
||||
}
|
||||
} else if metricsType == 1 {
|
||||
|
|
@ -44,7 +44,7 @@ func TelemetryToCsvFile(telemetry: [TelemetryEntity], metricsType: Int) -> Strin
|
|||
csvString += ", "
|
||||
csvString += String(dm.current)
|
||||
csvString += ", "
|
||||
csvString += dm.time?.formattedDate(format: "yyyy-MM-dd HH:mm:ss") ?? "Unknown Age"
|
||||
csvString += dm.time?.formattedDate(format: "yyyy-MM-dd HH:mm:ss") ?? NSLocalizedString("unknown.age", comment: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ func PositionToCsvFile(positions: [PositionEntity]) -> String {
|
|||
csvString += ", "
|
||||
csvString += String(pos.snr)
|
||||
csvString += ", "
|
||||
csvString += pos.time?.formattedDate(format: "yyyy-MM-dd HH:mm:ss") ?? "Unknown Age"
|
||||
csvString += pos.time?.formattedDate(format: "yyyy-MM-dd HH:mm:ss") ?? NSLocalizedString("unknown.age", comment: "")
|
||||
}
|
||||
return csvString
|
||||
}
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
|
|||
case .rangeTestApp:
|
||||
MeshLogger.log("ℹ️ MESH PACKET received for Range Test App UNHANDLED \(try! decodedInfo.packet.jsonString())")
|
||||
case .telemetryApp:
|
||||
if !invalidVersion { telemetryPacket(packet: decodedInfo.packet, context: context!) }
|
||||
if !invalidVersion { telemetryPacket(packet: decodedInfo.packet, connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0), context: context!) }
|
||||
case .textMessageCompressedApp:
|
||||
MeshLogger.log("ℹ️ MESH PACKET received for Text Message Compressed App UNHANDLED \(try! decodedInfo.packet.jsonString())")
|
||||
case .zpsApp:
|
||||
|
|
|
|||
|
|
@ -1189,7 +1189,7 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana
|
|||
}
|
||||
}
|
||||
|
||||
func telemetryPacket(packet: MeshPacket, context: NSManagedObjectContext) {
|
||||
func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManagedObjectContext) {
|
||||
|
||||
if let telemetryMessage = try? Telemetry(serializedData: packet.decoded.payload) {
|
||||
|
||||
|
|
@ -1235,7 +1235,10 @@ func telemetryPacket(packet: MeshPacket, context: NSManagedObjectContext) {
|
|||
}
|
||||
|
||||
try context.save()
|
||||
MeshLogger.log("💾 Telemetry Saved for Node: \(packet.from)")
|
||||
// Only log telemetery from the mesh not the connected device
|
||||
if connectedNode != Int64(packet.from) {
|
||||
MeshLogger.log("💾 Telemetry Saved for Node: \(packet.from)")
|
||||
}
|
||||
|
||||
} catch {
|
||||
context.rollback()
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ struct DateTimeText: View {
|
|||
|
||||
} else {
|
||||
|
||||
Text("Unknown Age")
|
||||
Text("unknown.age")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,9 +67,9 @@ struct ChannelMessageList: View {
|
|||
.cornerRadius(15)
|
||||
.contextMenu {
|
||||
VStack{
|
||||
Text("Channel: \(message.channel)")
|
||||
Text("channel")+Text(": \(message.channel)")
|
||||
}
|
||||
Menu("Tapback response") {
|
||||
Menu("tapback") {
|
||||
ForEach(Tapbacks.allCases) { tb in
|
||||
Button(action: {
|
||||
if bleManager.sendMessage(message: tb.emojiString, toUserNum: 0, channel: channel.index, isEmoji: true, replyID: message.messageId) {
|
||||
|
|
@ -89,16 +89,16 @@ struct ChannelMessageList: View {
|
|||
self.focusedField = .messageText
|
||||
print("I want to reply to \(message.messageId)")
|
||||
}) {
|
||||
Text("Reply")
|
||||
Text("reply")
|
||||
Image(systemName: "arrowshape.turn.up.left.2.fill")
|
||||
}
|
||||
Button(action: {
|
||||
UIPasteboard.general.string = message.messagePayload
|
||||
}) {
|
||||
Text("Copy")
|
||||
Text("copy")
|
||||
Image(systemName: "doc.on.doc")
|
||||
}
|
||||
Menu("Message Details") {
|
||||
Menu("message.details") {
|
||||
VStack {
|
||||
let messageDate = Date(timeIntervalSince1970: TimeInterval(message.messageTimestamp))
|
||||
Text("Date \(messageDate, style: .date) \(messageDate.formattedDate(format: "h:mm:ss a"))").font(.caption2).foregroundColor(.gray)
|
||||
|
|
@ -110,11 +110,11 @@ struct ChannelMessageList: View {
|
|||
}
|
||||
if currentUser && message.receivedACK {
|
||||
VStack {
|
||||
Text("Received Ack \(message.receivedACK ? "✔️" : "")")
|
||||
Text("received.ack")+Text(" \(message.receivedACK ? "✔️" : "")")
|
||||
}
|
||||
} else if currentUser && message.ackError == 0 {
|
||||
// Empty Error
|
||||
Text("Waiting. . .")
|
||||
Text("waiting")
|
||||
} else if currentUser && message.ackError > 0 {
|
||||
let ackErrorVal = RoutingError(rawValue: Int(message.ackError))
|
||||
Text("\(ackErrorVal?.display ?? "No Error" )").fixedSize(horizontal: false, vertical: true)
|
||||
|
|
@ -126,7 +126,7 @@ struct ChannelMessageList: View {
|
|||
if ackDate >= sixMonthsAgo! {
|
||||
Text((ackDate.formattedDate(format: "h:mm:ss a"))).font(.caption2).foregroundColor(.gray)
|
||||
} else {
|
||||
Text("Unknown Age").font(.caption2).foregroundColor(.gray)
|
||||
Text("unknown.age").font(.caption2).foregroundColor(.gray)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -243,12 +243,12 @@ struct ChannelMessageList: View {
|
|||
}
|
||||
|
||||
} label: {
|
||||
Text("share.positon")
|
||||
Text("share.position")
|
||||
Image(systemName: "mappin.and.ellipse")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.imageScale(.large).foregroundColor(.accentColor)
|
||||
}
|
||||
ProgressView("Bytes: \(totalBytes) / \(maxbytes)", value: Double(totalBytes), total: Double(maxbytes))
|
||||
ProgressView("\(NSLocalizedString("bytes", comment: "")): \(totalBytes) / \(maxbytes)", value: Double(totalBytes), total: Double(maxbytes))
|
||||
.frame(width: 130)
|
||||
.padding(5)
|
||||
.font(.subheadline)
|
||||
|
|
@ -260,7 +260,7 @@ struct ChannelMessageList: View {
|
|||
|
||||
ZStack {
|
||||
let kbType = UIKeyboardType(rawValue: UserDefaults.standard.object(forKey: "keyboardType") as? Int ?? 0)
|
||||
TextField("Message", text: $typingMessage, axis: .vertical)
|
||||
TextField("message", text: $typingMessage, axis: .vertical)
|
||||
.onChange(of: typingMessage, perform: { value in
|
||||
totalBytes = value.utf8.count
|
||||
// Only mess with the value if it is too big
|
||||
|
|
@ -300,7 +300,7 @@ struct ChannelMessageList: View {
|
|||
.imageScale(.large).foregroundColor(.accentColor)
|
||||
}
|
||||
|
||||
ProgressView("Bytes: \(totalBytes) / \(maxbytes)", value: Double(totalBytes), total: Double(maxbytes))
|
||||
ProgressView("\(NSLocalizedString("bytes", comment: "")): \(totalBytes) / \(maxbytes)", value: Double(totalBytes), total: Double(maxbytes))
|
||||
.frame(width: 130)
|
||||
.padding(5)
|
||||
.font(.subheadline)
|
||||
|
|
|
|||
|
|
@ -68,9 +68,9 @@ struct UserMessageList: View {
|
|||
.cornerRadius(15)
|
||||
.contextMenu {
|
||||
VStack{
|
||||
Text("Channel: \(message.channel)")
|
||||
Text("channel")+Text(": \(message.channel)")
|
||||
}
|
||||
Menu("Tapback response") {
|
||||
Menu("tapback") {
|
||||
ForEach(Tapbacks.allCases) { tb in
|
||||
Button(action: {
|
||||
if bleManager.sendMessage(message: tb.emojiString, toUserNum: user.num, channel: 0, isEmoji: true, replyID: message.messageId) {
|
||||
|
|
@ -90,16 +90,16 @@ struct UserMessageList: View {
|
|||
self.focusedField = .messageText
|
||||
print("I want to reply to \(message.messageId)")
|
||||
}) {
|
||||
Text("Reply")
|
||||
Text("reply")
|
||||
Image(systemName: "arrowshape.turn.up.left.2.fill")
|
||||
}
|
||||
Button(action: {
|
||||
UIPasteboard.general.string = message.messagePayload
|
||||
}) {
|
||||
Text("Copy")
|
||||
Text("copy")
|
||||
Image(systemName: "doc.on.doc")
|
||||
}
|
||||
Menu("Message Details") {
|
||||
Menu("message.details") {
|
||||
VStack {
|
||||
let messageDate = Date(timeIntervalSince1970: TimeInterval(message.messageTimestamp))
|
||||
Text("Date \(messageDate, style: .date) \(messageDate.formattedDate(format: "h:mm:ss a"))").font(.caption2).foregroundColor(.gray)
|
||||
|
|
@ -111,11 +111,11 @@ struct UserMessageList: View {
|
|||
}
|
||||
if currentUser && message.receivedACK {
|
||||
VStack {
|
||||
Text("Received Ack \(message.receivedACK ? "✔️" : "")")
|
||||
Text("received.ack")+Text(" \(message.receivedACK ? "✔️" : "")")
|
||||
}
|
||||
} else if currentUser && message.ackError == 0 {
|
||||
// Empty Error
|
||||
Text("Waiting. . .")
|
||||
Text("waiting")
|
||||
} else if currentUser && message.ackError > 0 {
|
||||
let ackErrorVal = RoutingError(rawValue: Int(message.ackError))
|
||||
Text("\(ackErrorVal?.display ?? "No Error" )").fixedSize(horizontal: false, vertical: true)
|
||||
|
|
@ -174,14 +174,14 @@ struct UserMessageList: View {
|
|||
}
|
||||
}
|
||||
HStack {
|
||||
let ackErrorVal = RoutingError(rawValue: Int(message.ackError))
|
||||
if currentUser && message.receivedACK {
|
||||
// Ack Received
|
||||
Text("Acknowledged").font(.caption2).foregroundColor(.gray)
|
||||
Text("\(ackErrorVal?.display ?? "No Error" )").font(.caption2).foregroundColor(.gray)
|
||||
} else if currentUser && message.ackError == 0 {
|
||||
// Empty Error
|
||||
Text("Waiting to be acknowledged. . .").font(.caption2).foregroundColor(.orange)
|
||||
} else if currentUser && message.ackError > 0 {
|
||||
let ackErrorVal = RoutingError(rawValue: Int(message.ackError))
|
||||
Text("\(ackErrorVal?.display ?? "No Error" )").fixedSize(horizontal: false, vertical: true)
|
||||
.font(.caption2).foregroundColor(.red)
|
||||
}
|
||||
|
|
@ -243,12 +243,12 @@ struct UserMessageList: View {
|
|||
}
|
||||
|
||||
} label: {
|
||||
Text("share.postion")
|
||||
Text("share.position")
|
||||
Image(systemName: "mappin.and.ellipse")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.imageScale(.large).foregroundColor(.accentColor)
|
||||
}
|
||||
ProgressView("Bytes: \(totalBytes) / \(maxbytes)", value: Double(totalBytes), total: Double(maxbytes))
|
||||
ProgressView("\(NSLocalizedString("bytes", comment: "")): \(totalBytes) / \(maxbytes)", value: Double(totalBytes), total: Double(maxbytes))
|
||||
.frame(width: 130)
|
||||
.padding(5)
|
||||
.font(.subheadline)
|
||||
|
|
@ -260,7 +260,7 @@ struct UserMessageList: View {
|
|||
HStack(alignment: .top) {
|
||||
ZStack {
|
||||
let kbType = UIKeyboardType(rawValue: UserDefaults.standard.object(forKey: "keyboardType") as? Int ?? 0)
|
||||
TextField("Message", text: $typingMessage, axis: .vertical)
|
||||
TextField("message", text: $typingMessage, axis: .vertical)
|
||||
.onChange(of: typingMessage, perform: { value in
|
||||
totalBytes = value.utf8.count
|
||||
// Only mess with the value if it is too big
|
||||
|
|
@ -297,7 +297,7 @@ struct UserMessageList: View {
|
|||
.symbolRenderingMode(.hierarchical)
|
||||
.imageScale(.large).foregroundColor(.accentColor)
|
||||
}
|
||||
ProgressView("Bytes: \(totalBytes) / \(maxbytes)", value: Double(totalBytes), total: Double(maxbytes))
|
||||
ProgressView("\(NSLocalizedString("bytes", comment: "")): \(totalBytes) / \(maxbytes)", value: Double(totalBytes), total: Double(maxbytes))
|
||||
.frame(width: 130)
|
||||
.padding(5)
|
||||
.font(.subheadline)
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ struct NodeDetail: View {
|
|||
.font(.title)
|
||||
.foregroundColor(.accentColor)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("User Id:").font(.title)
|
||||
Text("user").font(.title)+Text(":").font(.title)
|
||||
}
|
||||
//Text(node.user?.userId ?? "??????").font(.title).foregroundColor(.gray)
|
||||
Text("!\(String(format:"%02x", node.num))")
|
||||
|
|
@ -176,7 +176,7 @@ struct NodeDetail: View {
|
|||
.font(.title)
|
||||
.foregroundColor(.accentColor)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("Last Heard: ").font(.title)
|
||||
Text("heard.last").font(.title)+Text(":").font(.title)
|
||||
|
||||
}
|
||||
DateTimeText(dateTime: node.lastHeard)
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ struct MQTTConfig: View {
|
|||
.autocorrectionDisabled()
|
||||
|
||||
HStack {
|
||||
Label("Username", systemImage: "person.text.rectangle")
|
||||
TextField("Server Username", text: $username)
|
||||
Label("mqtt.username", systemImage: "person.text.rectangle")
|
||||
TextField("mqtt.username", text: $username)
|
||||
.foregroundColor(.gray)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
|
|
@ -105,8 +105,8 @@ struct MQTTConfig: View {
|
|||
.keyboardType(.default)
|
||||
.scrollDismissesKeyboard(.interactively)
|
||||
HStack {
|
||||
Label("Password", systemImage: "wallet.pass")
|
||||
TextField("Server Password", text: $password)
|
||||
Label("password", systemImage: "wallet.pass")
|
||||
TextField("password", text: $password)
|
||||
.foregroundColor(.gray)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
|
|
|
|||
|
|
@ -41,20 +41,20 @@ struct SerialConfig: View {
|
|||
|
||||
Toggle(isOn: $echo) {
|
||||
|
||||
Label("Echo", systemImage: "repeat")
|
||||
Label("echo", systemImage: "repeat")
|
||||
}
|
||||
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
||||
Text("If set, any packets you send will be echoed back to your device.")
|
||||
.font(.caption)
|
||||
|
||||
Picker("Baud Rate", selection: $baudRate ) {
|
||||
Picker("Baud", selection: $baudRate ) {
|
||||
ForEach(SerialBaudRates.allCases) { sbr in
|
||||
Text(sbr.description)
|
||||
}
|
||||
}
|
||||
.pickerStyle(DefaultPickerStyle())
|
||||
|
||||
Picker("Timeout", selection: $timeout ) {
|
||||
Picker("timeout", selection: $timeout ) {
|
||||
ForEach(SerialTimeoutIntervals.allCases) { sti in
|
||||
Text(sti.description)
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ struct SerialConfig: View {
|
|||
Text("The amount of time to wait before we consider your packet as done.")
|
||||
.font(.caption)
|
||||
|
||||
Picker("Mode", selection: $mode ) {
|
||||
Picker("mode", selection: $mode ) {
|
||||
ForEach(SerialModeTypes.allCases) { smt in
|
||||
Text(smt.description)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ struct TelemetryConfig: View {
|
|||
|
||||
VStack {
|
||||
Form {
|
||||
Section(header: Text("Update Intervals")) {
|
||||
Section(header: Text("update.interval")) {
|
||||
Picker("Device Metrics", selection: $deviceUpdateInterval ) {
|
||||
ForEach(UpdateIntervals.allCases) { ui in
|
||||
Text(ui.description)
|
||||
|
|
|
|||
|
|
@ -37,8 +37,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)
|
||||
|
|
@ -58,8 +58,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)
|
||||
|
|
|
|||
|
|
@ -10,16 +10,29 @@
|
|||
"admin"="Admin";
|
||||
"admin.log"="Admin Message Log";
|
||||
"ago"="ago";
|
||||
"always.on"="Always On";
|
||||
"app.settings"="App Settings";
|
||||
"are.you.sure"="Are you sure?";
|
||||
"ascii.capable"="ASCII Capable";
|
||||
"available.radios"="Available Radios";
|
||||
"automatic.detection"="Automatic Detection";
|
||||
"ble.name"="BLE Name";
|
||||
"bluetooth"="Bluetooth";
|
||||
"bluetooth.config"="Bluetooth Config";
|
||||
"bluetooth.mode.randompin"="Random PIN";
|
||||
"bluetooth.mode.fixedpin"="Fixed PIN";
|
||||
"bluetooth.mode.nopin"="No PIN (Just Works)";
|
||||
"bytes"="Bytes";
|
||||
"cancel"="Cancel";
|
||||
"canned.messages"="Canned Messages";
|
||||
"canned.messages.config"="Canned Messages Config";
|
||||
"canned.messages.preset.manual"="Manual Configuration";
|
||||
"canned.messages.preset.rakrotary"="RAK Rotary Encoder Module";
|
||||
"canned.messages.preset.cardkb"="M5 Stack Card KB / RAK Keypad";
|
||||
"channel"="Channel";
|
||||
"channel.role.disabled"="Disabled";
|
||||
"channel.role.primary"="Primary";
|
||||
"channel.role.secondary"="Secondary";
|
||||
"channels"="Channels (groups)";
|
||||
"clear.app.data"="Clear App Data";
|
||||
"connected.radio"="Connected Radio";
|
||||
|
|
@ -27,31 +40,62 @@
|
|||
"connected"="Currently Connected";
|
||||
"connecting"="Connecting . .";
|
||||
"contacts"="Contacts";
|
||||
"copy"="Copy";
|
||||
"default"="Default";
|
||||
"delete"="Delete";
|
||||
"device"="Device";
|
||||
"device.config"="Device Config";
|
||||
"device.role.client"="Client (default) - App connected client.";
|
||||
"device.role.clientmute"="Client Mute - Same as a client except packets will not hop over this node, does not contribute to routing packets for mesh.";
|
||||
"device.role.router"="Router - Mesh packets will prefer to be routed over this node. This node will not be used by client apps. The wifi/ble radios and the oled screen will be put to sleep.";
|
||||
"device.role.routerclient"="Router Client - Mesh packets will prefer to be routed over this node. The Router Client can be used as both a Router and an app connected Client.";
|
||||
"direct.messages"="Direct Messages";
|
||||
"dismiss.keyboard"="Dismiss Keyboard";
|
||||
"display"="Display (Device Screen)";
|
||||
"display.config"="Display Config";
|
||||
"distance"="Distance";
|
||||
"disconnect"="Disconnect";
|
||||
"echo"="Echo";
|
||||
"email.address"="Email Address";
|
||||
"enabled"="Enabled";
|
||||
"external.notification"="External Notification";
|
||||
"external.notification.config"="External Notification Config";
|
||||
"firmware.version"="Firmware Version";
|
||||
"gpsformat.dec"="Decimal Degrees Format";
|
||||
"gpsformat.dms"="Degrees Minutes Seconds";
|
||||
"gpsformat.utm"="Universal Transverse Mercator";
|
||||
"gpsformat.mgrs"="Military Grid Reference System";
|
||||
"gpsformat.olc"="Open Location Code (aka Plus Codes)";
|
||||
"gpsformat.osgr"="Ordnance Survey Grid Reference";
|
||||
"heard"="Heard";
|
||||
"heard.last"="Last Heard";
|
||||
"hybrid"="Hybrid";
|
||||
"inputevent.none"="None";
|
||||
"inputevent.up"="Up";
|
||||
"inputevent.down"="Down";
|
||||
"inputevent.left"="Left";
|
||||
"inputevent.right"="Right";
|
||||
"inputevent.select"="Select";
|
||||
"inputevent.back"="Back";
|
||||
"inputevent.cancel"="Cancel";
|
||||
"interval.one.second"="One Second";
|
||||
"interval.two.seconds"="Two Seconds";
|
||||
"interval.five.seconds"="Five Seconds";
|
||||
"interval.ten.seconds"="Ten Seconds";
|
||||
"interval.fifteen.seconds"="Fifteen Seconds";
|
||||
"interval.twenty.seconds"="Twenty Seconds";
|
||||
"interval.twentyfive.seconds"="Twenty Five Seconds";
|
||||
"interval.thirty.seconds"="Thirty Seconds";
|
||||
"interval.one.minute"="One Minute";
|
||||
"interval.two.minutes"="Two Minutes";
|
||||
"interval.five.minutes"="Five Minutes";
|
||||
"interval.ten.minutes"="Ten Minutes";
|
||||
"interval.fifteen.minutes"="Fifteen Minutes";
|
||||
"interval.thirty.minutes"="Thirty Minutes";
|
||||
"interval.one.hour"="One Hour";
|
||||
"interval.six.hours"="Six Hours";
|
||||
"interval.twelve.hours"="Twelve Hours";
|
||||
"interval.twentyfour.hours"="Twenty Four Hours";
|
||||
"keyboard.type"="Keyboard Type";
|
||||
"logging"="Logging";
|
||||
"lora"="LoRa";
|
||||
|
|
@ -59,17 +103,24 @@
|
|||
"map"="Mesh Map";
|
||||
"map.type"="Map Type";
|
||||
"mesh.log"="Mesh Log";
|
||||
"message"="Message";
|
||||
"message.details"="Message Details";
|
||||
"messages"="Messages";
|
||||
"mode"="Mode";
|
||||
"module.configuration"="Module Configuration";
|
||||
"mqtt"="MQTT";
|
||||
"mqtt.config"="MQTT Config";
|
||||
"mqtt.username"="Username";
|
||||
"network"="Network";
|
||||
"network.config"="Network Config";
|
||||
"nodes"="Nodes";
|
||||
"no.nodes"="No Meshtastic Nodes Found";
|
||||
"not.connected"="No device connected";
|
||||
"numbers.punctuation"="Numbers and Punctuation";
|
||||
"off"="Off";
|
||||
"on.boot"="On Boot Only";
|
||||
"options"="Options";
|
||||
"password"="Password";
|
||||
"phone.gps"="Phone GPS";
|
||||
"phone.gps.interval.description"="How frequently your phone will send your location to the device, location updates to the mesh are managed by the device.";
|
||||
"position"="Position";
|
||||
|
|
@ -79,10 +130,29 @@
|
|||
"radio.configuration"="Radio Configuration";
|
||||
"range.test"="Range Test";
|
||||
"range.test.config"="Range Test Config";
|
||||
"reply"="Reply";
|
||||
"received.ack"="Received Ack";
|
||||
"routing.acknowledged"="Acknowledged";
|
||||
"routing.noroute"="No Route";
|
||||
"routing.gotnak"="Received a negative acknowledgment";
|
||||
"routing.timeout"="Timeout";
|
||||
"routing.nointerface"="No Interface";
|
||||
"routing.maxretransmit"="Max Retransmission Reached";
|
||||
"routing.nochannel"="No Channel";
|
||||
"routing.toolarge"="The packet is too large";
|
||||
"routing.noresponse"="No Response";
|
||||
"routing.dutycyclelimit"="Regional Duty Cycle Limit Reached";
|
||||
"routing.badRequest"="Bad Request";
|
||||
"routing.notauthorized"="Not Authorized";
|
||||
"satellite"="Satellite";
|
||||
"save"="Save";
|
||||
"serial"="Serial";
|
||||
"serial.config"="Serial Config";
|
||||
"serial.mode.default"="Default";
|
||||
"serial.mode.simple"="Simple";
|
||||
"serial.mode.proto"="Protobufs";
|
||||
"serial.mode.txtmsg"="Text Message";
|
||||
"serial.mode.nmea"="NMEA Positions";
|
||||
"settings"="Settings";
|
||||
"share.channels"="Share Channels QR Code";
|
||||
"share.position"="Share Position";
|
||||
|
|
@ -92,10 +162,21 @@
|
|||
"select.menu.item"="Select an item from the menu";
|
||||
"set.region"="Set LoRa Region";
|
||||
"standard"="Standard";
|
||||
"ssid"="SSID";
|
||||
"tapback"="Tapback Response";
|
||||
"tapback.heart"="Heart";
|
||||
"tapback.thumbsup"="Thumbs Up";
|
||||
"tapback.thumbsdown"="Thumbs Down";
|
||||
"tapback.haha"="HaHa";
|
||||
"tapback.exclamation"="Exclamation Mark";
|
||||
"tapback.question"="Question Mark";
|
||||
"tapback.poop"="Poop";
|
||||
"telemetry"="Telemetry (Sensors)";
|
||||
"telemetry.config"="Telemetry Config";
|
||||
"timeout"="timeout"
|
||||
"twitter"="Twitter";
|
||||
"unknown.age"="Unknown Age";
|
||||
"update.interval"="Update Interval";
|
||||
"user"="User";
|
||||
"user.details"="User Details";
|
||||
"waiting"="Waiting. . .";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue