Fix username on mqtt config save

Set mqtt.address character limit to 62
This commit is contained in:
Garth Vander Houwen 2023-03-24 10:35:54 -07:00
parent 0a0f7f01cb
commit 93ffd8c72d
6 changed files with 133 additions and 32 deletions

View file

@ -108,6 +108,8 @@
DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */; };
DDC3B274283F411B00AC321C /* LastHeardText.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC3B273283F411B00AC321C /* LastHeardText.swift */; };
DDC4D568275499A500A4208E /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC4D567275499A500A4208E /* Persistence.swift */; };
DDC94FC129CE063B0082EA6E /* BatteryLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC94FC029CE063B0082EA6E /* BatteryLevel.swift */; };
DDC94FC229CE063B0082EA6E /* BatteryLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC94FC029CE063B0082EA6E /* BatteryLevel.swift */; };
DDCDC6CB29481FCC004C1DDA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DDCDC6CD29481FCC004C1DDA /* Localizable.strings */; };
DDCE4E2C2869F92900BE9F8F /* UserConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCE4E2B2869F92900BE9F8F /* UserConfig.swift */; };
DDD3BBD5292D763200D609B3 /* MeshtasticTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDD3BBD4292D763200D609B3 /* MeshtasticTests.swift */; };
@ -282,6 +284,7 @@
DDC2E1A626CEB3400042C5E4 /* LocationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationHelper.swift; sourceTree = "<group>"; };
DDC3B273283F411B00AC321C /* LastHeardText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LastHeardText.swift; sourceTree = "<group>"; };
DDC4D567275499A500A4208E /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
DDC94FC029CE063B0082EA6E /* BatteryLevel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryLevel.swift; sourceTree = "<group>"; };
DDCDC69A29467643004C1DDA /* MeshtasticDataModelV3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV3.xcdatamodel; sourceTree = "<group>"; };
DDCDC6CC29481FCC004C1DDA /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
DDCDC6CE294821AD004C1DDA /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
@ -677,6 +680,7 @@
DDDE59FC29AF163D00490C6C /* Widgets.swift */,
DDDE5A0029AF163E00490C6C /* Info.plist */,
DDDE5A0F29AFE69700490C6C /* MeshActivityAttributes.swift */,
DDC94FC029CE063B0082EA6E /* BatteryLevel.swift */,
);
path = Widgets;
sourceTree = "<group>";
@ -901,6 +905,7 @@
DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */,
DD964FBD296E6B01007C176F /* EmojiOnlyTextField.swift in Sources */,
DD8169FF272476C700F4AB02 /* LogDocument.swift in Sources */,
DDC94FC129CE063B0082EA6E /* BatteryLevel.swift in Sources */,
DD2AD8A8296D2DF9001FF0E7 /* MapViewSwiftUI.swift in Sources */,
DD5E5213298EE33B00D21B61 /* deviceonly.pb.swift in Sources */,
DD5E5208298EE33B00D21B61 /* rtttl.pb.swift in Sources */,
@ -1003,6 +1008,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DDC94FC229CE063B0082EA6E /* BatteryLevel.swift in Sources */,
DDDE5A1129AFE69700490C6C /* MeshActivityAttributes.swift in Sources */,
DDDE59FB29AF163D00490C6C /* WidgetsLiveActivity.swift in Sources */,
DDDE59FD29AF163D00490C6C /* Widgets.swift in Sources */,

View file

@ -719,7 +719,7 @@ func upsertMqttModuleConfigPacket(config: Meshtastic.ModuleConfig.MQTTConfig, no
let newMQTTConfig = MQTTConfigEntity(context: context)
newMQTTConfig.enabled = config.enabled
newMQTTConfig.address = config.address
newMQTTConfig.address = config.username
newMQTTConfig.username = config.username
newMQTTConfig.password = config.password
newMQTTConfig.encryptionEnabled = config.encryptionEnabled
newMQTTConfig.jsonEnabled = config.jsonEnabled
@ -727,7 +727,7 @@ func upsertMqttModuleConfigPacket(config: Meshtastic.ModuleConfig.MQTTConfig, no
} else {
fetchedNode[0].mqttConfig?.enabled = config.enabled
fetchedNode[0].mqttConfig?.address = config.address
fetchedNode[0].mqttConfig?.address = config.username
fetchedNode[0].mqttConfig?.username = config.username
fetchedNode[0].mqttConfig?.password = config.password
fetchedNode[0].mqttConfig?.encryptionEnabled = config.encryptionEnabled
fetchedNode[0].mqttConfig?.jsonEnabled = config.jsonEnabled

View file

@ -79,8 +79,8 @@ struct MQTTConfig: View {
.onChange(of: address, perform: { _ in
let totalBytes = address.utf8.count
// Only mess with the value if it is too big
if totalBytes > 30 {
let firstNBytes = Data(username.utf8.prefix(30))
if totalBytes > 62 {
let firstNBytes = Data(username.utf8.prefix(62))
if let maxBytesString = String(data: firstNBytes, encoding: String.Encoding.utf8) {
// Set the shortName back to the last place where it was the right size
address = maxBytesString

View file

@ -224,7 +224,7 @@ struct ShareChannels: View {
.font(.headline)
.padding(.bottom)
Text("Primary Channel").font(.title2)
Text("The first channel is the Primary channel and is where much of the mesh activity takes place. DM's are only available on the primary channel and it can not be disabled.")
Text("The first channel is the Primary channel and is where much of the mesh activity takes place. DM's are only available on the primary channel and it can not be disabled. If you don't share your primary channel, the first channel will become the primary channel on the other network and will allow communication with your mesh on the group channel.")
.font(.callout)
.padding([.leading, .trailing, .bottom])
Text("Admin Channel").font(.title2)

View file

@ -0,0 +1,76 @@
//
// BatteryLevel.swift
// Meshtastic
//
// Copyright Garth Vander Houwen 3/24/23.
//
import SwiftUI
struct BatteryIcon: View {
var batteryLevel: Int32?
var font: Font
var color: Color
var body: some View {
if batteryLevel == 100 {
Image(systemName: "battery.100.bolt")
.font(font)
.foregroundColor(color)
.symbolRenderingMode(.hierarchical)
} else if batteryLevel! < 100 && batteryLevel! > 74 {
Image(systemName: "battery.75")
.font(font)
.foregroundColor(color)
.symbolRenderingMode(.hierarchical)
} else if batteryLevel! < 75 && batteryLevel! > 49 {
Image(systemName: "battery.50")
.font(font)
.foregroundColor(color)
.symbolRenderingMode(.hierarchical)
} else if batteryLevel! < 50 && batteryLevel! > 14 {
Image(systemName: "battery.25")
.font(font)
.foregroundColor(color)
.symbolRenderingMode(.hierarchical)
} else if batteryLevel! < 15 && batteryLevel! >= 0 {
Image(systemName: "battery.0")
.font(font)
.foregroundColor(.red)
.symbolRenderingMode(.hierarchical)
} else if batteryLevel! > 100 {
Image(systemName: "powerplug")
.font(font)
.foregroundColor(color)
.symbolRenderingMode(.hierarchical)
}
else {
Image(systemName: "battery.0")
.font(font)
.foregroundColor(color)
.symbolRenderingMode(.hierarchical)
}
}
}
struct BatteryIcon_Previews: PreviewProvider {
static var previews: some View {
BatteryIcon(batteryLevel: 100, font: .title2, color: Color.accentColor)
.previewLayout(.fixed(width: 75, height: 75))
BatteryIcon(batteryLevel: 99, font: .title2, color: Color.accentColor)
.previewLayout(.fixed(width: 75, height: 75))
BatteryIcon(batteryLevel: 74, font: .title2, color: Color.accentColor)
.previewLayout(.fixed(width: 75, height: 75))
BatteryIcon(batteryLevel: 49, font: .title2, color: Color.accentColor)
.previewLayout(.fixed(width: 75, height: 75))
BatteryIcon(batteryLevel: 14, font: .title2, color: Color.accentColor)
.previewLayout(.fixed(width: 75, height: 75))
}
}

View file

@ -20,22 +20,49 @@ struct WidgetsLiveActivity: Widget {
} dynamicIsland: { context in
DynamicIsland {
DynamicIslandExpandedRegion(.leading) {
NodeInfoView(nodeName: context.attributes.name, timerRange: context.state.timerRange, channelUtilization: context.state.channelUtilization, airtime: context.state.airtime, batteryLevel: context.state.batteryLevel)
.tint(Color("LightIndigo"))
.padding(.top)
Text("Network")
.font(.headline)
.fontWeight(.bold)
.foregroundStyle(.secondary)
.fixedSize()
.padding(.top, 10)
Text("\(String(format: "Ch. Util: %.2f", context.state.channelUtilization))%")
.font(.headline)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.fixedSize()
Text("\(String(format: "Airtime: %.2f", context.state.airtime))%")
.font(.headline)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.fixedSize()
Spacer()
}
// Expanded UI goes here. Compose the expanded UI through
// various regions, like leading/trailing/center/bottom
DynamicIslandExpandedRegion(.trailing, priority: 1) {
HStack(alignment: .lastTextBaseline) {
Spacer()
TimerView(timerRange: context.state.timerRange)
.tint(Color("LightIndigo"))
DynamicIslandExpandedRegion(.center) {
VStack(alignment: .center, spacing: 0) {
BatteryIcon(batteryLevel: Int32(context.state.batteryLevel), font: .title, color: .accentColor)
Text(String(context.state.batteryLevel) + "%")
.font(.title3)
.foregroundColor(.gray)
.fixedSize()
}
.padding(.top)
}
DynamicIslandExpandedRegion(.trailing, priority: 1) {
TimerView(timerRange: context.state.timerRange)
.tint(Color("LightIndigo"))
}
DynamicIslandExpandedRegion(.bottom){
Text(context.attributes.name)
.font(context.attributes.name.count > 14 ? .callout : .title3)
.fontWeight(.semibold)
.foregroundStyle(.tint)
Text("Last Heard: \(Date().formatted())")
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.fixedSize()
}
} compactLeading: {
Image("logo-black")
@ -65,7 +92,7 @@ struct WidgetsLiveActivity: Widget {
@available(iOS 16.2, *)
struct WidgetsLiveActivity_Previews: PreviewProvider {
static let attributes = MeshActivityAttributes(nodeNum: 123456789, name: "Meshtastic 8E6G")
static let attributes = MeshActivityAttributes(nodeNum: 123456789, name: "RAK Compact Rotary Handset Gray 8E6G")
static let state = MeshActivityAttributes.ContentState(
timerRange: Date.now...Date(timeIntervalSinceNow: 3600), connected: true, channelUtilization: 25.84, airtime: 10.01, batteryLevel: 39)
@ -134,34 +161,34 @@ struct NodeInfoView: View {
.fontWeight(.semibold)
.foregroundStyle(.tint)
Text("\(String(format: "Ch. Util: %.2f", channelUtilization))%")
.font(.subheadline)
.font(.headline)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
.fixedSize()
Text("\(String(format: "Airtime: %.2f", airtime))%")
.font(.subheadline)
.font(.headline)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
.fixedSize()
if batteryLevel < 101 {
Text("Battery Level: \(batteryLevel > 0 ? String(batteryLevel) : "< 1")%")
.font(.subheadline)
.font(.headline)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
.fixedSize()
} else {
Text("Plugged In")
.font(.subheadline)
.font(.headline)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
.fixedSize()
}
Text(Date().formatted())
.font(.subheadline)
.font(.headline)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.8 : 1.0)
@ -177,18 +204,11 @@ struct TimerView: View {
var body: some View {
VStack(alignment: .center) {
Text("NEXT")
Text("NEXT UPDATE")
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.5 : 1.0)
.fixedSize()
Text("UPDATE")
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
.opacity(isLuminanceReduced ? 0.5 : 1.0)
.fixedSize()
Text(timerInterval: timerRange, countsDown: true)
.monospacedDigit()
.multilineTextAlignment(.center)
@ -215,7 +235,6 @@ struct ExpandedTrailingView: View {
var body: some View {
HStack(alignment: .lastTextBaseline) {
Spacer()
TimerView(timerRange: timerInterval)
}