Fix nil coordinates crash

This commit is contained in:
Garth Vander Houwen 2021-12-18 20:49:50 -08:00
parent 7336000588
commit 58156d4f56
17 changed files with 148 additions and 206 deletions

View file

@ -15,7 +15,6 @@
DD47E3DB26F3901B00029299 /* Channels.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3DA26F3901A00029299 /* Channels.swift */; };
DD47E3DD26F390A000029299 /* Messages.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD47E3DC26F390A000029299 /* Messages.swift */; };
DD4A911E2708C65400501B7E /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4A911D2708C65400501B7E /* AppSettings.swift */; };
DD4A91202708C66600501B7E /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4A911F2708C66600501B7E /* Configuration.swift */; };
DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */ = {isa = PBXBuildFile; productRef = DD5394FB276993AD00AD86B1 /* SwiftProtobuf */; };
DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */; };
DD539500276C452400AD86B1 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5394FF276C452400AD86B1 /* Preferences.swift */; };
@ -76,7 +75,6 @@
DD47E3DA26F3901A00029299 /* Channels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Channels.swift; sourceTree = "<group>"; };
DD47E3DC26F390A000029299 /* Messages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Messages.swift; sourceTree = "<group>"; };
DD4A911D2708C65400501B7E /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.swift; sourceTree = "<group>"; };
DD4A911F2708C66600501B7E /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = "<group>"; };
DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionEntityExtension.swift; sourceTree = "<group>"; };
DD5394FF276C452400AD86B1 /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
DD539501276DAA6A00AD86B1 /* MapLocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLocation.swift; sourceTree = "<group>"; };
@ -165,7 +163,6 @@
isa = PBXGroup;
children = (
DD4A911D2708C65400501B7E /* AppSettings.swift */,
DD4A911F2708C66600501B7E /* Configuration.swift */,
DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */,
DD8169FE272476C700F4AB02 /* LogDocument.swift */,
);
@ -503,7 +500,6 @@
DDAF8C6926ED0D070058C060 /* deviceonly.pb.swift in Sources */,
DDAF8C6B26ED0DD80058C060 /* environmental_measurement.pb.swift in Sources */,
DD90860C26F684AF00DC5189 /* BatteryIcon.swift in Sources */,
DD4A91202708C66600501B7E /* Configuration.swift in Sources */,
DD4A911E2708C65400501B7E /* AppSettings.swift in Sources */,
DDAF8C6226ED0A230058C060 /* mqtt.pb.swift in Sources */,
DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */,
@ -695,7 +691,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.28.3;
MARKETING_VERSION = 1.31;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;
@ -722,7 +718,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.28.3;
MARKETING_VERSION = 1.31;
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTS_MACCATALYST = YES;

View file

@ -64,38 +64,6 @@
landmarkType = "14">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "2CAE774E-7819-413A-91D3-559FCC82C1FB"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "MeshtasticClient/Helpers/BLEManager.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "826"
endingLineNumber = "826"
landmarkName = "sendMessage(message:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "BE4B1DBA-2314-49AB-B64E-4DB2EBF1A1C7"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "MeshtasticClient/Helpers/BLEManager.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "849"
endingLineNumber = "849"
landmarkName = "sendMessage(message:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
@ -112,53 +80,5 @@
landmarkType = "24">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "9E5EE071-FC2A-41A4-BDBD-6F21C3B68B91"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "MeshtasticClient/Helpers/BLEManager.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "665"
endingLineNumber = "665"
landmarkName = "peripheral(_:didUpdateValueFor:error:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "D6E2764E-1AE9-4717-9EE0-3826937B39A2"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "MeshtasticClient/Helpers/BLEManager.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "708"
endingLineNumber = "708"
landmarkName = "peripheral(_:didUpdateValueFor:error:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "FCCE5870-E475-42D6-AB90-5632098DC9FB"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "MeshtasticClient/Helpers/BLEManager.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "482"
endingLineNumber = "482"
landmarkName = "peripheral(_:didUpdateValueFor:error:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

View file

@ -1,14 +1,17 @@
{
"images" : [
{
"filename" : "tlora-2.jpeg",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "tlora-3.jpeg",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "tlora-4.jpeg",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

View file

@ -1,14 +1,17 @@
{
"images" : [
{
"filename" : "tlora-2.jpeg",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "tlora-3.jpeg",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "tlora-4.jpeg",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

View file

@ -25,7 +25,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
@Published var peripherals = [Peripheral]()
@Published var connectedPeripheral: Peripheral!
@Published var connectedNode: NodeInfoEntity!
//@Published var connectedNode: NodeInfoEntity!
@Published var lastConnectedPeripheral: String
@Published var lastConnectionError: String
@ -37,6 +37,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
var timeoutTimerCount = 0
private var broadcastNodeId: UInt32 = 4294967295
var nextSentMessageId: Int64 = 1
/* Meshtastic Service Details */
var TORADIO_characteristic: CBCharacteristic!
@ -211,6 +212,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
if fetchedNode.count == 1 {
connectedPeripheral.num = fetchedNode[0].user!.num
connectedPeripheral.shortName = fetchedNode[0].user!.shortName!
connectedPeripheral.longName = fetchedNode[0].user!.longName!
connectedPeripheral.firmwareVersion = (fetchedNode[0].myInfo?.firmwareVersion ?? "Unknown")
@ -480,19 +482,17 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
newNode.user = newUser
}
//if decodedInfo.nodeInfo.hasPosition && decodedInfo.nodeInfo.position.latitudeI != 0 {
let position = PositionEntity(context: context!)
position.latitudeI = decodedInfo.nodeInfo.position.latitudeI
position.longitudeI = decodedInfo.nodeInfo.position.longitudeI
position.altitude = decodedInfo.nodeInfo.position.altitude
position.batteryLevel = decodedInfo.nodeInfo.position.batteryLevel
position.time = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.position.time)))
let position = PositionEntity(context: context!)
position.latitudeI = decodedInfo.nodeInfo.position.latitudeI
position.longitudeI = decodedInfo.nodeInfo.position.longitudeI
position.altitude = decodedInfo.nodeInfo.position.altitude
position.batteryLevel = decodedInfo.nodeInfo.position.batteryLevel
position.time = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.position.time)))
var newPostions = [PositionEntity]()
newPostions.append(position)
newNode.positions? = NSOrderedSet(array : newPostions)
//}
var newPostions = [PositionEntity]()
newPostions.append(position)
newNode.positions? = NSOrderedSet(array : newPostions)
// Look for a MyInfo
let fetchMyInfoRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MyInfoEntity")
@ -524,21 +524,18 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
fetchedNode[0].user!.shortName = decodedInfo.nodeInfo.user.shortName
fetchedNode[0].user!.hwModel = String(describing: decodedInfo.nodeInfo.user.hwModel).uppercased()
}
if decodedInfo.nodeInfo.hasPosition && decodedInfo.nodeInfo.position.latitudeI != 0 && decodedInfo.nodeInfo.position.longitudeI != 0 {
let position = PositionEntity(context: context!)
position.latitudeI = decodedInfo.nodeInfo.position.latitudeI
position.longitudeI = decodedInfo.nodeInfo.position.longitudeI
position.altitude = decodedInfo.nodeInfo.position.altitude
position.batteryLevel = decodedInfo.nodeInfo.position.batteryLevel
position.time = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.position.time)))
let position = PositionEntity(context: context!)
position.latitudeI = decodedInfo.nodeInfo.position.latitudeI
position.longitudeI = decodedInfo.nodeInfo.position.longitudeI
position.altitude = decodedInfo.nodeInfo.position.altitude
position.batteryLevel = decodedInfo.nodeInfo.position.batteryLevel
position.time = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.nodeInfo.position.time)))
if position.latitudeI != 0 {
let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet
mutablePositions.add(position)
fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet
}
}
let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet
mutablePositions.add(position)
fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet
// Look for a MyInfo
let fetchMyInfoRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MyInfoEntity")
fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(decodedInfo.nodeInfo.num))
@ -611,20 +608,21 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
newMessage.messageTimestamp = Int32(bitPattern: decodedInfo.packet.rxTime)
newMessage.receivedACK = false
newMessage.direction = "IN"
newMessage.toUser = Int64(decodedInfo.packet.to)
if decodedInfo.packet.to == broadcastNodeId && fetchedUsers.count == 1 {
let bcu: UserEntity = UserEntity(context: context!)
bcu.shortName = "BC"
bcu.longName = "Broadcast"
bcu.hwModel = "UNSET"
bcu.num = Int64(broadcastNodeId)
bcu.userId = "BROADCASTNODE"
newMessage.toUser = bcu
//let bcu: UserEntity = UserEntity(context: context!)
//bcu.shortName = "BC"
//bcu.longName = "Broadcast"
//bcu.hwModel = "UNSET"
//bcu.num = Int64(broadcastNodeId)
//bcu.userId = "BROADCASTNODE"
//newMessage.toUser = bcu
} else {
newMessage.toUser = fetchedUsers.first(where: { $0.num == decodedInfo.packet.to })
//return
//newMessage.toUser = fetchedUsers.first(where: { $0.num == decodedInfo.packet.to })
}
newMessage.fromUser = fetchedUsers.first(where: { $0.num == decodedInfo.packet.from })
@ -806,58 +804,70 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
// Don's send an empty message
success = false
} else {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = Int64(bitPattern: 0)
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "IN"
let bcu: UserEntity = UserEntity(context: context!)
bcu.shortName = "BC"
bcu.longName = "Broadcast"
bcu.hwModel = "UNSET"
bcu.num = Int64(broadcastNodeId)
bcu.userId = "BROADCASTNODE"
newMessage.toUser = bcu
// Set from user from query here
newMessage.messagePayload = message
let fetchFromUser:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "UserEntity")
fetchFromUser.predicate = NSPredicate(format: "num == %lld", Int64(self.connectedPeripheral.num))
let dataType = PortNum.textMessageApp
let payloadData: Data = message.data(using: String.Encoding.utf8)!
var dataMessage = DataMessage()
dataMessage.payload = payloadData
dataMessage.portnum = dataType
var meshPacket = MeshPacket()
meshPacket.to = broadcastNodeId
meshPacket.decoded = dataMessage
meshPacket.wantAck = true
var toRadio: ToRadio!
toRadio = ToRadio()
toRadio.packet = meshPacket
let binaryData: Data = try! toRadio.serializedData()
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
do {
do {
let fetchedUser = try context?.fetch(fetchFromUser) as! [UserEntity]
if fetchedUser.isEmpty {
try context!.save()
print("Saved a new message for \(0)")
success = true
} catch {
context!.rollback()
let nsError = error as NSError
print("Unresolved error \(nsError)")
print("Connected User Not Found, Fail")
success = false
}
else {
let newMessage = MessageEntity(context: context!)
newMessage.messageId = nextSentMessageId
newMessage.messageTimestamp = Int32(Date().timeIntervalSince1970)
newMessage.receivedACK = false
newMessage.direction = "IN"
newMessage.toUser = Int64(broadcastNodeId)
newMessage.fromUser = fetchedUser[0]
newMessage.messagePayload = message
let dataType = PortNum.textMessageApp
let payloadData: Data = message.data(using: String.Encoding.utf8)!
var dataMessage = DataMessage()
dataMessage.payload = payloadData
dataMessage.portnum = dataType
var meshPacket = MeshPacket()
meshPacket.to = broadcastNodeId
meshPacket.decoded = dataMessage
meshPacket.wantAck = true
var toRadio: ToRadio!
toRadio = ToRadio()
toRadio.packet = meshPacket
let binaryData: Data = try! toRadio.serializedData()
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
do {
try context!.save()
print("Saved a new sent message from \(connectedPeripheral.num)")
success = true
nextSentMessageId+=1
} catch {
context!.rollback()
let nsError = error as NSError
print("Unresolved error \(nsError)")
}
}
}
} catch {
}
}
return success

View file

@ -9,7 +9,7 @@ extension PositionEntity {
let d = Double(latitudeI)
if d == 0 {
return nil
return 0
}
return d / 1e7
}
@ -18,7 +18,7 @@ extension PositionEntity {
let d = Double(longitudeI)
if d == 0 {
return nil
return 0
}
return d / 1e7
}

View file

@ -60,6 +60,5 @@ struct ContentView: View {
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
// .environmentObject(MeshData())
}
}

View file

@ -43,12 +43,10 @@ struct MessageBubble: View {
Spacer()
}
.alert(isPresented: $showAlert) {
Alert(title: Text("Are you sure you want to delete this message?"), message: Text("This action is permanent."),
primaryButton: .destructive(Text("OK")) {
print("OK button tapped")
// let messageIndex = meshData.nodes.firstIndex(where: { $0.id == node.id })
// meshData.nodes.remove(at: nodeIndex!)
// meshData.save()
},
secondaryButton: .cancel()
)

View file

@ -48,12 +48,13 @@ struct Messages: View {
ForEach(messages) { message in
HStack(alignment: .top) {
let currentUser: Bool = false// (message.fromUser != nil && bleManager.connectedPeripheral.num == message.fromUser!.num)
let currentUser: Bool = (bleManager.connectedPeripheral == nil) ? false : ((bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.num == message.fromUser?.num) ? true : false )
//let currentUser: (Bool = message.fromUser == nil : false : (message.fromUser != nil && bleManager.connectedPeripheral.num == message.fromUser!.num : true)
CircleText(text: (message.fromUser?.longName ?? "???"), color: currentUser ? .accentColor : Color(.darkGray)).padding(.all, 5)
CircleText(text: (message.fromUser?.shortName ?? "???"), color: currentUser ? .accentColor : Color(.darkGray)).padding(.all, 5)
.gesture(LongPressGesture(minimumDuration: 2)
.onEnded {_ in
print(messages)
print("I want to delete message: \(message.messageId)")
self.showDeleteMessageAlert = true
self.deleteMessageId = message.messageId
@ -94,8 +95,8 @@ struct Messages: View {
context.delete(message!)
do {
try context.save()
deleteMessageId = 0
messageCount = messages.count
@ -182,6 +183,7 @@ struct Messages: View {
Button(action: {
if bleManager.sendMessage(message: typingMessage) {
typingMessage = ""
focusedField = nil
} else {
_ = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false) { (_) in
@ -204,14 +206,14 @@ struct Messages: View {
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(trailing:
ZStack {
ZStack {
ConnectedDevice(
bluetoothOn: bleManager.isSwitchedOn,
deviceConnected: bleManager.connectedPeripheral != nil,
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName :
"???")
})
ConnectedDevice(
bluetoothOn: bleManager.isSwitchedOn,
deviceConnected: bleManager.connectedPeripheral != nil,
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???")
}
)
.onAppear(perform: {
self.bleManager.context = context

View file

@ -58,7 +58,10 @@ struct NodeDetail: View {
HStack {
Image(systemName: "clock").font(.title).foregroundColor(.accentColor)
Image(systemName: "clock.badge.checkmark.fill")
.font(.title)
.foregroundColor(.accentColor)
.symbolRenderingMode(.hierarchical)
Text("Last Heard: \(node.lastHeard!, style: .relative) ago").font(.title3)
}
.padding()
@ -117,7 +120,10 @@ struct NodeDetail: View {
.padding(.bottom)
if mostRecent.batteryLevel > 0 {
Text("Battery").font(.title2).fixedSize()
Text("Battery")
.font(.title2)
.fixedSize()
.textCase(.uppercase)
Text(String(mostRecent.batteryLevel) + "%")
.font(.title2)
.foregroundColor(.gray)
@ -127,6 +133,7 @@ struct NodeDetail: View {
Text("Powered")
.font(.callout)
.fixedSize()
.textCase(.uppercase)
}
}
.padding(5)
@ -139,7 +146,10 @@ struct NodeDetail: View {
HStack(alignment: .center) {
VStack {
HStack {
Image(systemName: "person").font(.title2).foregroundColor(.accentColor)
Image(systemName: "person")
.font(.title2)
.foregroundColor(.accentColor)
.symbolRenderingMode(.hierarchical)
Text("Unique Id:").font(.title2)
}
Text(node.user?.userId ?? "??????").font(.title3).foregroundColor(.gray)
@ -147,7 +157,10 @@ struct NodeDetail: View {
Divider()
VStack {
HStack {
Image(systemName: "number").font(.title2).foregroundColor(.accentColor)
Image(systemName: "number")
.font(.title2)
.foregroundColor(.accentColor)
.symbolRenderingMode(.hierarchical)
Text("Node Number:").font(.title2)
}
Text(String(node.num)).font(.title3).foregroundColor(.gray)
@ -160,7 +173,10 @@ struct NodeDetail: View {
HStack {
Image(systemName: "map.circle.fill").font(.title).foregroundColor(.accentColor)
Image(systemName: "map.circle.fill")
.font(.title)
.foregroundColor(.accentColor)
.symbolRenderingMode(.hierarchical)
Text("Position History (\(node.positions?.count ?? 0) Points)").font(.title2)
}
.padding()
@ -206,23 +222,26 @@ struct NodeDetail: View {
.symbolRenderingMode(.hierarchical)
}
}
.padding([.top, .bottom])
.padding(1)
Divider()
}
.padding(.bottom, 5) // Without some padding here there is a transparent contentview bug
}
}
}.navigationTitle(node.user!.longName ?? "Unknown")
}
.navigationTitle(node.user!.longName ?? "Unknown")
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(trailing:
ZStack {
ZStack {
ConnectedDevice(
bluetoothOn: bleManager.isSwitchedOn,
deviceConnected: bleManager.connectedPeripheral != nil,
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName :
"???")
})
ConnectedDevice(
bluetoothOn: bleManager.isSwitchedOn,
deviceConnected: bleManager.connectedPeripheral != nil,
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???")
}
)
.onAppear(perform: {
self.bleManager.context = context

View file

@ -1,8 +0,0 @@
//
// Configuration.swift
// MeshtasticClient
//
// Created by Garth Vander Houwen on 10/2/21.
//
import Foundation