Channels help

This commit is contained in:
Garth Vander Houwen 2025-06-18 17:51:09 -07:00
parent ca6cf606bc
commit 63bc7a5805
5 changed files with 123 additions and 2 deletions

View file

@ -1683,6 +1683,12 @@
}
}
}
},
"A channel index of 0 indicates the primary channel where all broadcast packets are sent from." : {
},
"A green lock means the channel is securely encrypted with either a 128 or 256 bit AES key." : {
},
"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." : {
"localizations" : {
@ -1741,6 +1747,9 @@
}
}
}
},
"A red lock with a slash means the channel is not securely encrypted, it uses either no key at all or a 1 byte known key. Traffic on this channel is easily intercepted." : {
},
"A Trace Route was sent, no response has been received." : {
"localizations" : {
@ -6162,6 +6171,9 @@
}
}
}
},
"Channels Help" : {
},
"Chart" : {
"localizations" : {

View file

@ -99,6 +99,7 @@
DD1BD0F32C63C65E008C0C70 /* SecurityConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BD0F22C63C65E008C0C70 /* SecurityConfig.swift */; };
DD1BEF4A2E0292320090CE24 /* KeychainHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BEF492E0292220090CE24 /* KeychainHelper.swift */; };
DD1BEF4C2E030D310090CE24 /* KeyBackupStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BEF4B2E030D240090CE24 /* KeyBackupStatus.swift */; };
DD1BEF4E2E03916A0090CE24 /* ChannelsHelp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BEF4D2E0391620090CE24 /* ChannelsHelp.swift */; };
DD1BF2F92776FE2E008C8D2F /* UserMessageList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */; };
DD2160AF28C5552500C17253 /* MQTTConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2160AE28C5552500C17253 /* MQTTConfig.swift */; };
DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */; };
@ -376,6 +377,7 @@
DD1BEF462DFF284C0090CE24 /* MeshtasticDataModelV 53.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 53.xcdatamodel"; sourceTree = "<group>"; };
DD1BEF492E0292220090CE24 /* KeychainHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainHelper.swift; sourceTree = "<group>"; };
DD1BEF4B2E030D240090CE24 /* KeyBackupStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyBackupStatus.swift; sourceTree = "<group>"; };
DD1BEF4D2E0391620090CE24 /* ChannelsHelp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelsHelp.swift; sourceTree = "<group>"; };
DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserMessageList.swift; sourceTree = "<group>"; };
DD2160AE28C5552500C17253 /* MQTTConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MQTTConfig.swift; sourceTree = "<group>"; };
DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeripheralModel.swift; sourceTree = "<group>"; };
@ -850,6 +852,7 @@
DD6F65772C6EAB860053C113 /* Help */ = {
isa = PBXGroup;
children = (
DD1BEF4D2E0391620090CE24 /* ChannelsHelp.swift */,
DD6F65752C6EA5490053C113 /* AckErrors.swift */,
DD6F65782C6EADE60053C113 /* DirectMessagesHelp.swift */,
DD6F657A2C6EC2900053C113 /* LockLegend.swift */,
@ -1428,6 +1431,7 @@
D9C9839D2B79CFD700BDBE6A /* TextMessageSize.swift in Sources */,
DDC94FCE29CF55310082EA6E /* RtttlConfig.swift in Sources */,
DD964FBD296E6B01007C176F /* EmojiOnlyTextField.swift in Sources */,
DD1BEF4E2E03916A0090CE24 /* ChannelsHelp.swift in Sources */,
DD8169FF272476C700F4AB02 /* LogDocument.swift in Sources */,
BCD93CBA2D9E11A2006C9214 /* DisconnectNodeIntent.swift in Sources */,
DDC94FC129CE063B0082EA6E /* BatteryLevel.swift in Sources */,

View file

@ -0,0 +1,76 @@
//
// ChannelHelp.swift
// Meshtastic
//
// Copyright(c) Garth Vander Houwen 6/18/25.
//
import SwiftUI
struct ChannelsHelp: View {
private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom }
@Environment(\.dismiss) private var dismiss
var body: some View {
ScrollView {
Label("Channels Help", systemImage: "questionmark.circle")
.font(.title)
.padding(.vertical)
VStack(alignment: .leading) {
HStack {
CircleText(text: String(0), color: .accentColor)
.brightness(0.2)
.offset(y: -10)
Text("A channel index of 0 indicates the primary channel where all broadcast packets are sent from.")
.fixedSize(horizontal: false, vertical: true)
.padding(.bottom)
}
HStack {
Image(systemName: "lock.fill")
.padding(.bottom)
.foregroundColor(Color.green)
.font(.largeTitle)
Text("A green lock means the channel is securely encrypted with either a 128 or 256 bit AES key.")
.fixedSize(horizontal: false, vertical: true)
.padding(.bottom)
}
HStack {
Image(systemName: "lock.slash.fill")
.padding(.bottom)
.foregroundColor(Color.red)
.font(.largeTitle)
Text("A red lock with a slash means the channel is not securely encrypted, it uses either no key at all or a 1 byte known key. Traffic on this channel is easily intercepted.")
.fixedSize(horizontal: false, vertical: true)
.padding(.bottom)
}
}
#if targetEnvironment(macCatalyst)
Spacer()
Button {
dismiss()
} label: {
Label("Close", systemImage: "xmark")
}
.buttonStyle(.bordered)
.buttonBorderShape(.capsule)
.controlSize(.large)
.padding(.bottom)
#endif
}
.frame(minHeight: 0, maxHeight: .infinity, alignment: .leading)
.padding()
.presentationDetents([.large])
.presentationContentInteraction(.scrolls)
.presentationDragIndicator(.visible)
.presentationBackgroundInteraction(.enabled(upThrough: .large))
}
}
struct ChannelHelpPreviews: PreviewProvider {
static var previews: some View {
VStack {
ChannelsHelp()
}
}
}

View file

@ -21,8 +21,8 @@ struct ChannelList: View {
var channelSelection: ChannelEntity?
@State private var isPresentingDeleteChannelMessagesConfirm: Bool = false
@State private var isPresentingTraceRouteSentAlert = false
@State private var showingHelp = false
var restrictedChannels = ["gpio", "mqtt", "serial", "admin"]
@ -168,8 +168,30 @@ struct ChannelList: View {
}
.padding([.top, .bottom])
.listStyle(.plain)
.navigationTitle("Channels")
}
}
.navigationTitle("Channels")
.sheet(isPresented: $showingHelp) {
ChannelsHelp()
.presentationDetents([.medium])
}
.safeAreaInset(edge: .bottom, alignment: .leading) {
HStack {
Button(action: {
withAnimation {
showingHelp = !showingHelp
}
}) {
Image(systemName: !showingHelp ? "questionmark.circle" : "questionmark.circle.fill")
.padding(.vertical, 5)
}
.tint(Color(UIColor.secondarySystemBackground))
.foregroundColor(.accentColor)
.buttonStyle(.borderedProminent)
}
.controlSize(.regular)
.padding(5)
}
.padding(.bottom, 5)
}
}

View file

@ -124,6 +124,13 @@ struct Channels: View {
.brightness(0.1)
VStack {
HStack {
if channel.psk?.hexDescription.count ?? 0 < 3 {
Image(systemName: "lock.slash.fill")
.foregroundColor(.red)
} else {
Image(systemName: "lock.fill")
.foregroundColor(.green)
}
if channel.name?.isEmpty ?? false {
if channel.role == 1 {
Text(String("PrimaryChannel").camelCaseToWords()).font(.headline)