mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
* Update messaging list separator insets
* Dont show unread messages or notifications for emoji reactions matching iMessage.
* Restore ble state method (#1416)
* Restore BLE State
* Log privacy
* AccessoryManager to handle restored connection
* Comment task out
* Update restore state function based on conversation with jake
* Update Meshtastic/Accessory/Transports/Bluetooth Low Energy/BLETransport.swift
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update Meshtastic/Accessory/Transports/Bluetooth Low Energy/BLETransport.swift
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Jake-B <jake-b@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Two Column Node List (#1425)
* Restore BLE State
* Log privacy
* AccessoryManager to handle restored connection
* Comment task out
* Switch the node list to a two column layout
* Keep asian translations of channel details string
* Update restore state function based on conversation with jake
* Update Meshtastic/Accessory/Transports/Bluetooth Low Energy/BLETransport.swift
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update Meshtastic/Accessory/Transports/Bluetooth Low Energy/BLETransport.swift
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* always show node list search bar
* Update auto correct modifier
* Dont show online animations for ios 17, remove online animation from node map, remove online circle from position popover
* Work in progress.
* Update detents
* Gate the discovery process while restoring
* Use geometry reader to size weather tiles on node details
* Update BLE Transport
* Update location weather condistion styles
* Log privacy in didReceive
* Remove extra dividers from admin key config, fix onboarding typo
* Bump minimum catalyst target
* Bump mac target version
* Use @FetchRequest for UserList to try and use less memory on ios 17
* Revert change to @fetchrequest
* Stab in the dark for Devices crash
* Updated UserList (back?) to @FetchRequest
* Set mac minimum to 15
* Nil out continuation after use
* Use @FetchRequest for the node list to stop crashes on iOS 17
* Handle failed connections during restoration
---------
Co-authored-by: Jake-B <jake-b@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update protos
* Update protos
* Remove stale keys
* Serbian translations update (#1422)
* Log privacy
* Add Serbian translations
---------
Co-authored-by: Garth Vander Houwen <garthvh@yahoo.com>
* Clarify public key sub-text in security settings (#1412)
* Clarify public key sub-text in settings
* Trigger lint
* freq slot num pad (#1410)
* kill keyboard toolbar on lora config
* delete extranious scrollDismissesKeyboard
* Properly set catalyst target
* Update Meshtastic/Views/Onboarding/DeviceOnboarding.swift
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update Meshtastic/Views/Settings/Config/SecurityConfig.swift
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update Meshtastic/Enums/DeviceEnums.swift
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Make current location nilable, remove log spam
* clean up toUser logic
* Fix telemetry entity not added in nodeInfoPacket
* fix typo: powerMetrics.hasChXCurrent mismatch
* Duplicate decoding of telemetry.current removed
* Clean up mesh map fetch request and distance filter logic
* Revert attempt to fix message logic
* Bump datadog version
* Missing message fix, attempt #2 (#1431)
Co-authored-by: Jake-B <jake-b@users.noreply.github.com>
* Retry fewer times for longer
* Revert "Missing message fix, attempt #2 (#1431)" (#1432)
This reverts commit a96d318adb.
* Make retry 2 seconds
* Add back link to node details from position popover without navigation stack and link, clear notifications when deleting database
* Add clear notifications function
* Link from channel messages to node info
* Link to node details
* Discovery on retry fix
* Discovery on retry fix fix
* Add contact to device node db if you get an encrypted send faild routing error
* Seperate channel message view into two views for better performance.
* Refactor User Message List
* Update device hardware
Add liquid glass to config save button
* Save button cleanup
* Update button structure on users view
* Move encrypted send logic out of the router. Update protos
* Restore node long- and short- names (#1442)
Co-authored-by: Jake-B <jake-b@users.noreply.github.com>
* Update Meshtastic/Accessory/Transports/Bluetooth Low Energy/BLEConnection.swift
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Revert routing error
* Toggle for enabling device telemetry broadcast enable
* Update
* Enhancements for interval dropdowns (#1445)
* Cleanup
* Fix core data version
* Add never to update interval
* Device telemetry Enabled Boolean (#1446)
* Update core data and interval picker
* Move formatter
* Rework to nest options under enabled
* Clearer names
* Safer devicehardware api call, remove node history filter from mesh map
* Fix build
* Simplify mesh map filter
* Remove stale translation keys
---------
Co-authored-by: Jake-B <jake-b@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Nikola Dašić <dasic.nikola@yandex.com>
Co-authored-by: Spencer Smith <dontaskspencer@gmail.com>
Co-authored-by: Benjamin Faershtein <119711889+RCGV1@users.noreply.github.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
252 lines
6.3 KiB
Swift
252 lines
6.3 KiB
Swift
//
|
|
// ChannelForm.swift
|
|
// Meshtastic
|
|
//
|
|
// Copyright(c) Garth Vander Houwen 3/17/24.
|
|
//
|
|
|
|
import SwiftUI
|
|
import MapKit
|
|
|
|
struct ChannelForm: View {
|
|
|
|
@Binding var channelIndex: Int32
|
|
@Binding var channelName: String
|
|
@Binding var channelKeySize: Int
|
|
@Binding var channelKey: String
|
|
@Binding var channelRole: Int
|
|
@Binding var uplink: Bool
|
|
@Binding var downlink: Bool
|
|
@Binding var positionPrecision: Double
|
|
@Binding var preciseLocation: Bool
|
|
@Binding var positionsEnabled: Bool
|
|
@Binding var hasChanges: Bool
|
|
@Binding var hasValidKey: Bool
|
|
@Binding var supportedVersion: Bool
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
Form {
|
|
Section(header: Text("Channel Details")) {
|
|
HStack {
|
|
Text("Name")
|
|
Spacer()
|
|
TextField(
|
|
"Channel Name",
|
|
text: $channelName
|
|
)
|
|
.disableAutocorrection(true)
|
|
.keyboardType(.alphabet)
|
|
.foregroundColor(Color.gray)
|
|
.onChange(of: channelName) {
|
|
channelName = channelName.replacing(" ", with: "")
|
|
var totalBytes = channelName.utf8.count
|
|
// Only mess with the value if it is too big
|
|
while totalBytes > 11 {
|
|
channelName = String(channelName.dropLast())
|
|
totalBytes = channelName.utf8.count
|
|
}
|
|
hasChanges = true
|
|
}
|
|
}
|
|
HStack {
|
|
Picker("Key Size", selection: $channelKeySize) {
|
|
Text("Empty").tag(0)
|
|
Text("Default").tag(-1)
|
|
Text("1 byte").tag(1)
|
|
Text("128 bit").tag(16)
|
|
Text("256 bit").tag(32)
|
|
}
|
|
.pickerStyle(DefaultPickerStyle())
|
|
Spacer()
|
|
Button {
|
|
if channelKeySize == -1 {
|
|
channelKey = "AQ=="
|
|
} else {
|
|
let key = generateChannelKey(size: channelKeySize)
|
|
channelKey = key
|
|
}
|
|
} label: {
|
|
Image(systemName: "lock.rotation")
|
|
.font(.title)
|
|
}
|
|
.buttonStyle(.bordered)
|
|
.buttonBorderShape(.capsule)
|
|
.controlSize(.small)
|
|
}
|
|
HStack(alignment: .center) {
|
|
Text("Key")
|
|
Spacer()
|
|
TextField(
|
|
"Key",
|
|
text: $channelKey,
|
|
axis: .vertical
|
|
)
|
|
.padding(6)
|
|
.disableAutocorrection(true)
|
|
.keyboardType(.alphabet)
|
|
.foregroundColor(Color.gray)
|
|
.textSelection(.enabled)
|
|
.background(
|
|
RoundedRectangle(cornerRadius: 10.0)
|
|
.stroke(
|
|
hasValidKey ?
|
|
Color.clear :
|
|
Color.red
|
|
, lineWidth: 2.0)
|
|
|
|
)
|
|
.onChange(of: channelKey) {
|
|
|
|
let tempKey = Data(base64Encoded: channelKey) ?? Data()
|
|
if tempKey.count == channelKeySize || channelKeySize == -1 {
|
|
hasValidKey = true
|
|
} else {
|
|
hasValidKey = false
|
|
}
|
|
hasChanges = true
|
|
}
|
|
.disabled(channelKeySize <= 0)
|
|
}
|
|
HStack {
|
|
if channelRole == 1 {
|
|
Picker("Channel Role", selection: $channelRole) {
|
|
Text("Primary").tag(1)
|
|
}
|
|
.pickerStyle(.automatic)
|
|
.disabled(true)
|
|
} else {
|
|
Text("Channel Role")
|
|
Spacer()
|
|
Picker("Channel Role", selection: $channelRole) {
|
|
Text("Disabled").tag(0)
|
|
Text("Secondary").tag(2)
|
|
}
|
|
.pickerStyle(.segmented)
|
|
}
|
|
}
|
|
}
|
|
|
|
Section(header: Text("Position")) {
|
|
VStack(alignment: .leading) {
|
|
Toggle(isOn: $positionsEnabled) {
|
|
Label(channelRole == 1 ? "Positions Enabled" : "Allow Position Requests", systemImage: positionsEnabled ? "mappin" : "mappin.slash")
|
|
}
|
|
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
|
.disabled(!supportedVersion)
|
|
}
|
|
|
|
if positionsEnabled {
|
|
if (channelKey != "AQ==" && channelKeySize > 1) && channelRole > 0 {
|
|
VStack(alignment: .leading) {
|
|
Toggle(isOn: $preciseLocation) {
|
|
Label("Precise Location", systemImage: "scope")
|
|
}
|
|
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
|
.disabled(!supportedVersion)
|
|
.listRowSeparator(.visible)
|
|
.onChange(of: preciseLocation) { _, pl in
|
|
if pl == false {
|
|
positionPrecision = 15
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if !preciseLocation {
|
|
VStack(alignment: .leading) {
|
|
Label("Approximate Location", systemImage: "location.slash.circle.fill")
|
|
|
|
Slider(value: $positionPrecision, in: 12...15, step: 1) {
|
|
} minimumValueLabel: {
|
|
Image(systemName: "plus")
|
|
} maximumValueLabel: {
|
|
Image(systemName: "minus")
|
|
}
|
|
Text(PositionPrecision(rawValue: Int(positionPrecision))?.description ?? "")
|
|
.foregroundColor(.gray)
|
|
.font(.callout)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Section(header: Text("MQTT")) {
|
|
Toggle(isOn: $uplink) {
|
|
Label("Uplink Enabled", systemImage: "arrowshape.up")
|
|
}
|
|
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
|
.listRowSeparator(.visible)
|
|
|
|
Toggle(isOn: $downlink) {
|
|
Label("Downlink Enabled", systemImage: "arrowshape.down")
|
|
}
|
|
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
|
|
}
|
|
}
|
|
.onChange(of: channelName) {
|
|
hasChanges = true
|
|
}
|
|
.onChange(of: channelKeySize) {
|
|
if channelKeySize == -1 {
|
|
channelKey = "AQ=="
|
|
} else {
|
|
let key = generateChannelKey(size: channelKeySize)
|
|
channelKey = key
|
|
}
|
|
hasChanges = true
|
|
}
|
|
.onChange(of: channelKey) {
|
|
hasChanges = true
|
|
}
|
|
.onChange(of: channelKeySize) {
|
|
if channelKeySize == -1 {
|
|
if channelRole == 0 {
|
|
preciseLocation = false
|
|
}
|
|
channelKey = "AQ=="
|
|
}
|
|
}
|
|
.onChange(of: channelRole) {
|
|
hasChanges = true
|
|
}
|
|
.onChange(of: preciseLocation) { _, loc in
|
|
if loc == true {
|
|
if channelKey == "AQ==" || channelKeySize <= 1 {
|
|
preciseLocation = false
|
|
} else {
|
|
positionPrecision = 32
|
|
}
|
|
} else {
|
|
positionPrecision = 14
|
|
}
|
|
hasChanges = true
|
|
}
|
|
.onChange(of: positionPrecision) {
|
|
hasChanges = true
|
|
}
|
|
.onChange(of: positionsEnabled) { _, pe in
|
|
if pe {
|
|
if positionPrecision == 0 {
|
|
positionPrecision = 15
|
|
}
|
|
} else {
|
|
positionPrecision = 0
|
|
}
|
|
hasChanges = true
|
|
}
|
|
.onChange(of: uplink) {
|
|
hasChanges = true
|
|
}
|
|
.onChange(of: downlink) {
|
|
hasChanges = true
|
|
}
|
|
.onFirstAppear {
|
|
let tempKey = Data(base64Encoded: channelKey) ?? Data()
|
|
if tempKey.count == channelKeySize || channelKeySize == -1 {
|
|
hasValidKey = true
|
|
} else {
|
|
hasValidKey = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|