mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
V 1.35 Connected Peripheral and MyInfo bugs
This commit is contained in:
parent
92c61f199f
commit
a8d08c0b9f
8 changed files with 183 additions and 104 deletions
|
|
@ -695,7 +695,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.33;
|
||||
MARKETING_VERSION = 1.35;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
@ -722,7 +722,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.33;
|
||||
MARKETING_VERSION = 1.35;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
|
|||
|
|
@ -80,22 +80,6 @@
|
|||
landmarkType = "24">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "77F5CE1E-8BA3-4831-8A0D-6CEE16E9E8FD"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "MeshtasticClient/Helpers/BLEManager.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "808"
|
||||
endingLineNumber = "808"
|
||||
landmarkName = "sendMessage(message:toUserNum:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
|
|
@ -106,8 +90,8 @@
|
|||
filePath = "MeshtasticClient/Helpers/BLEManager.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "894"
|
||||
endingLineNumber = "894"
|
||||
startingLineNumber = "897"
|
||||
endingLineNumber = "897"
|
||||
landmarkName = "sendMessage(message:toUserNum:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
|
|
@ -115,15 +99,15 @@
|
|||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "6D12B6E1-7FB9-466C-94FA-1BCA5CB64261"
|
||||
uuid = "04619ED9-EF12-49A5-9AEF-C115B206581C"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "MeshtasticClient/Helpers/BLEManager.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "505"
|
||||
endingLineNumber = "505"
|
||||
startingLineNumber = "469"
|
||||
endingLineNumber = "469"
|
||||
landmarkName = "peripheral(_:didUpdateValueFor:error:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
|
|
@ -131,15 +115,15 @@
|
|||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "332E0378-DE65-4ED3-ACB0-668EB8D62DE8"
|
||||
uuid = "F25765DD-CBAA-4892-8EE8-A632C79D42F0"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "MeshtasticClient/Helpers/BLEManager.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "405"
|
||||
endingLineNumber = "405"
|
||||
startingLineNumber = "466"
|
||||
endingLineNumber = "466"
|
||||
landmarkName = "peripheral(_:didUpdateValueFor:error:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
@Published var peripherals = [Peripheral]()
|
||||
|
||||
@Published var connectedPeripheral: Peripheral!
|
||||
//@Published var connectedNode: NodeInfoEntity!
|
||||
@Published var lastConnectedPeripheral: String
|
||||
@Published var lastConnectionError: String
|
||||
|
||||
|
|
@ -220,6 +219,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
} catch {
|
||||
print("💥 Fetch NodeInfo Failed")
|
||||
if meshLoggingEnabled { MeshLogger.log("💥 Fetch NodeInfo Failed") }
|
||||
}
|
||||
|
||||
lastConnectedPeripheral = peripheral.identifier.uuidString
|
||||
|
|
@ -257,8 +257,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
// We will try and re-connect to this device
|
||||
lastConnectionError = "🚫 \(e.localizedDescription) The app will automatically reconnect to the preferred radio if it reappears within 10 seconds."
|
||||
if peripheral.identifier.uuidString == UserDefaults.standard.object(forKey: "preferredPeripheralId") as? String ?? "" {
|
||||
if meshLoggingEnabled { MeshLogger.log("BLE Reconnecting: \(peripheral.name ?? "Unknown")") }
|
||||
print("BLE Reconnecting: \(peripheral.name ?? "Unknown")")
|
||||
if meshLoggingEnabled { MeshLogger.log("ℹ️ BLE Reconnecting: \(peripheral.name ?? "Unknown")") }
|
||||
print("ℹ️ BLE Reconnecting: \(peripheral.name ?? "Unknown")")
|
||||
self.connectTo(peripheral: peripheral)
|
||||
}
|
||||
} else if errorCode == 7 { // CBError.Code.peripheralDisconnected The specified device has disconnected from us.
|
||||
|
|
@ -340,7 +340,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
peripheral.readValue(for: FROMRADIO_characteristic)
|
||||
|
||||
case FROMNUM_UUID:
|
||||
print("FROMNUM (Notify) characteristic OK")
|
||||
print("✅ FROMNUM (Notify) characteristic OK")
|
||||
if meshLoggingEnabled { MeshLogger.log("✅ BLE did discover FROMNUM (Notify) characteristic for Meshtastic by \(peripheral.name ?? "Unknown")") }
|
||||
FROMNUM_characteristic = characteristic
|
||||
peripheral.setNotifyValue(true, for: characteristic)
|
||||
|
|
@ -390,14 +390,12 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
var decodedInfo = FromRadio()
|
||||
|
||||
decodedInfo = try! FromRadio(serializedData: characteristic.value!)
|
||||
print("Print DecodedInfo")
|
||||
print(decodedInfo)
|
||||
//print("Print DecodedInfo")
|
||||
//print(decodedInfo)
|
||||
|
||||
// MyInfo Data
|
||||
if decodedInfo.myInfo.myNodeNum != 0 {
|
||||
|
||||
print("💾 Save a CoreData MyInfoEntity")
|
||||
|
||||
let fetchMyInfoRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MyInfoEntity")
|
||||
fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(decodedInfo.myInfo.myNodeNum))
|
||||
|
||||
|
|
@ -413,6 +411,9 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
myInfo.messageTimeoutMsec = Int32(bitPattern: decodedInfo.myInfo.messageTimeoutMsec)
|
||||
myInfo.minAppVersion = Int32(bitPattern: decodedInfo.myInfo.minAppVersion)
|
||||
myInfo.maxChannels = Int32(bitPattern: decodedInfo.myInfo.maxChannels)
|
||||
connectedPeripheral.num = myInfo.myNodeNum
|
||||
connectedPeripheral.firmwareVersion = myInfo.firmwareVersion ?? "Unknown"
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
|
|
@ -439,17 +440,14 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
}
|
||||
|
||||
} catch {
|
||||
print("💥 Fetch MyInfo Error")
|
||||
|
||||
print("💥 Fetch MyInfo Error")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// NodeInfo Data
|
||||
if decodedInfo.nodeInfo.num != 0 {
|
||||
|
||||
print("💾 Save a CoreData NodeInfoEntity")
|
||||
|
||||
let fetchNodeRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
|
||||
fetchNodeRequest.predicate = NSPredicate(format: "num == %lld", Int64(decodedInfo.nodeInfo.num))
|
||||
|
||||
|
|
@ -469,12 +467,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
if self.connectedPeripheral != nil && self.connectedPeripheral.num == newNode.id {
|
||||
|
||||
newNode.bleName = self.connectedPeripheral.name
|
||||
|
||||
} else {
|
||||
|
||||
let userIdLast4: String = String(decodedInfo.nodeInfo.user.id.suffix(4))
|
||||
newNode.bleName = "Meshtastic_" + userIdLast4
|
||||
newNode.bleName = self.connectedPeripheral.peripheral.name
|
||||
if decodedInfo.nodeInfo.hasUser {
|
||||
|
||||
connectedPeripheral.name = decodedInfo.nodeInfo.user.longName
|
||||
connectedPeripheral.longName = decodedInfo.nodeInfo.user.longName
|
||||
connectedPeripheral.shortName = decodedInfo.nodeInfo.user.shortName
|
||||
}
|
||||
}
|
||||
|
||||
if decodedInfo.nodeInfo.hasUser {
|
||||
|
|
@ -486,6 +485,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
newUser.shortName = decodedInfo.nodeInfo.user.shortName
|
||||
newUser.macaddr = decodedInfo.nodeInfo.user.macaddr
|
||||
newUser.hwModel = String(describing: decodedInfo.nodeInfo.user.hwModel).uppercased()
|
||||
newUser.team = (String(describing: decodedInfo.nodeInfo.user.team))
|
||||
newNode.user = newUser
|
||||
}
|
||||
|
||||
|
|
@ -530,6 +530,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
fetchedNode[0].user!.longName = decodedInfo.nodeInfo.user.longName
|
||||
fetchedNode[0].user!.shortName = decodedInfo.nodeInfo.user.shortName
|
||||
fetchedNode[0].user!.hwModel = String(describing: decodedInfo.nodeInfo.user.hwModel).uppercased()
|
||||
fetchedNode[0].user!.team = (String(describing: decodedInfo.nodeInfo.user.team))
|
||||
}
|
||||
|
||||
let position = PositionEntity(context: context!)
|
||||
|
|
@ -625,9 +626,10 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
if decodedInfo.packet.to == broadcastNodeNum && fetchedUsers.count == 1 {
|
||||
|
||||
// Save the broadcast user if it does not exist
|
||||
let bcu: UserEntity = UserEntity(context: context!)
|
||||
bcu.shortName = "BC"
|
||||
bcu.longName = "Broadcast"
|
||||
bcu.shortName = "ALL"
|
||||
bcu.longName = "Broadcast (^all)"
|
||||
bcu.hwModel = "UNSET"
|
||||
bcu.num = Int64(broadcastNodeNum)
|
||||
bcu.userId = "BROADCASTNODE"
|
||||
|
|
@ -693,12 +695,10 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
return
|
||||
}
|
||||
do {
|
||||
// print(decodedInfo.packet.decoded.payload)
|
||||
|
||||
try context!.save()
|
||||
|
||||
if meshLoggingEnabled {
|
||||
MeshLogger.log("💾 Updated NodeInfo SNR and Time from Node Info App Packet For: \(Int64(decodedInfo.nodeInfo.num))")
|
||||
}
|
||||
if meshLoggingEnabled { MeshLogger.log("💾 Updated NodeInfo SNR and Time from Node Info App Packet For: \(Int64(decodedInfo.nodeInfo.num))")}
|
||||
print("💾 Updated NodeInfo SNR and Time from Packet For: \(fetchedNode[0].num)")
|
||||
|
||||
} catch {
|
||||
|
|
@ -714,8 +714,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
print("💥 Error Fetching NodeInfoEntity for NODEINFO_APP")
|
||||
}
|
||||
|
||||
print(decodedInfo.packet.decoded.payload)
|
||||
|
||||
} else if decodedInfo.packet.decoded.portnum == PortNum.positionApp {
|
||||
|
||||
let fetchNodePositionRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
|
||||
|
|
@ -728,7 +726,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
if fetchedNode.count == 1 {
|
||||
fetchedNode[0].id = Int64(decodedInfo.packet.from)
|
||||
fetchedNode[0].num = Int64(decodedInfo.packet.from)
|
||||
print(decodedInfo.packet.decoded.payload)
|
||||
if(decodedInfo.packet.rxTime == 0) {
|
||||
|
||||
fetchedNode[0].lastHeard = Date()
|
||||
|
|
@ -830,9 +827,11 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
success = false
|
||||
} else if message.count < 1 {
|
||||
// Don's send an empty message
|
||||
print("Don't Send an Empty Message")
|
||||
|
||||
// Don't send an empty message
|
||||
print("🚫 Don't Send an Empty Message")
|
||||
success = false
|
||||
|
||||
} else {
|
||||
|
||||
let fromUserNum:Int64 = self.connectedPeripheral.num
|
||||
|
|
@ -846,7 +845,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
if fetchedUsers.isEmpty {
|
||||
|
||||
print("Message Users Not Found, Fail")
|
||||
print("🚫 Message Users Not Found, Fail")
|
||||
success = false
|
||||
}
|
||||
else if fetchedUsers.count >= 1 {
|
||||
|
|
@ -860,8 +859,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
if newMessage.toUser == nil {
|
||||
|
||||
let bcu: UserEntity = UserEntity(context: context!)
|
||||
bcu.shortName = "BC"
|
||||
bcu.longName = "Broadcast"
|
||||
bcu.shortName = "ALL"
|
||||
bcu.longName = "Broadcast (^all)"
|
||||
bcu.hwModel = "UNSET"
|
||||
bcu.num = Int64(broadcastNodeNum)
|
||||
bcu.userId = "BROADCASTNODE"
|
||||
|
|
@ -888,6 +887,10 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
toRadio.packet = meshPacket
|
||||
|
||||
let binaryData: Data = try! toRadio.serializedData()
|
||||
|
||||
if meshLoggingEnabled { MeshLogger.log("📲 New message sent to \(newMessage.toUser?.longName! ?? "Unknown")") }
|
||||
print("📲 New message sent to \(newMessage.toUser?.longName! ?? "Unknown")")
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
do {
|
||||
|
|
@ -903,7 +906,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
context!.rollback()
|
||||
|
||||
let nsError = error as NSError
|
||||
print("Unresolved error \(nsError)")
|
||||
print("🚫 Unresolved error \(nsError)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
<attribute name="macaddr" optional="YES" attributeType="Binary"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="shortName" attributeType="String"/>
|
||||
<attribute name="team" optional="YES" attributeType="String"/>
|
||||
<attribute name="userId" attributeType="String"/>
|
||||
<relationship name="receivedMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="toUser" inverseEntity="MessageEntity"/>
|
||||
<relationship name="sentMessages" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="MessageEntity" inverseName="fromUser" inverseEntity="MessageEntity"/>
|
||||
|
|
@ -68,6 +69,6 @@
|
|||
<element name="MyInfoEntity" positionX="-18" positionY="81" width="128" height="149"/>
|
||||
<element name="NodeInfoEntity" positionX="-63" positionY="-18" width="128" height="149"/>
|
||||
<element name="PositionEntity" positionX="-54" positionY="54" width="128" height="119"/>
|
||||
<element name="UserEntity" positionX="0" positionY="144" width="128" height="164"/>
|
||||
<element name="UserEntity" positionX="0" positionY="144" width="128" height="179"/>
|
||||
</elements>
|
||||
</model>
|
||||
|
|
@ -21,22 +21,22 @@ struct MeshtasticClientApp: App {
|
|||
.onChange(of: scenePhase) { (newScenePhase) in
|
||||
switch newScenePhase {
|
||||
case .background:
|
||||
print("ℹ️ Scene is in the background")
|
||||
do {
|
||||
|
||||
try persistenceController.container.viewContext.save()
|
||||
print("Saved viewContext when the app went to the background.")
|
||||
print("💾 Saved CoreData ViewContext when the app went to the background.")
|
||||
|
||||
} catch {
|
||||
|
||||
print("Failed to save viewContext when the app goes to the background.")
|
||||
print("💥 Failed to save viewContext when the app goes to the background.")
|
||||
}
|
||||
print("Scene is in the background")
|
||||
case .inactive:
|
||||
print("Scene is inactive")
|
||||
print("ℹ️ Scene is inactive")
|
||||
case .active:
|
||||
print("Scene is active")
|
||||
print("ℹ️ Scene is active")
|
||||
@unknown default:
|
||||
print("Apple must have changed something")
|
||||
print("💥 Apple must have changed something")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ struct ContentView: View {
|
|||
@State private var selection: Tab = .ble
|
||||
|
||||
enum Tab {
|
||||
case contacts
|
||||
case messages
|
||||
case map
|
||||
case ble
|
||||
|
|
@ -18,6 +19,14 @@ struct ContentView: View {
|
|||
var body: some View {
|
||||
|
||||
TabView(selection: $selection) {
|
||||
// Contacts()
|
||||
// .tabItem {
|
||||
// Label("Contacts", systemImage: "person.crop.circle")
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
// .symbolVariant(.none)
|
||||
//
|
||||
// }
|
||||
// .tag(Tab.contacts)
|
||||
Channels()
|
||||
.tabItem {
|
||||
Label("Messages", systemImage: "text.bubble")
|
||||
|
|
|
|||
|
|
@ -8,8 +8,91 @@
|
|||
import SwiftUI
|
||||
|
||||
struct Contacts: View {
|
||||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
|
||||
@FetchRequest(
|
||||
sortDescriptors: [NSSortDescriptor(key: "longName", ascending: true)],
|
||||
animation: .default)
|
||||
|
||||
private var users: FetchedResults<UserEntity>
|
||||
|
||||
var body: some View {
|
||||
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
|
||||
NavigationView {
|
||||
List(users) { user in
|
||||
|
||||
if user.receivedMessages?.count ?? 0 > 0 {
|
||||
|
||||
let mostRecent = user.receivedMessages?.lastObject as! MessageEntity
|
||||
let lastMessageTime = Date(timeIntervalSince1970: TimeInterval(Int64(mostRecent.messageTimestamp)))
|
||||
let lastMessageDay = Calendar.current.dateComponents([.day], from: lastMessageTime).day ?? 0
|
||||
let currentDay = Calendar.current.dateComponents([.day], from: Date()).day ?? 0
|
||||
|
||||
HStack {
|
||||
VStack {
|
||||
CircleText(text: user.shortName ?? "???", color: Color.blue)
|
||||
}
|
||||
VStack {
|
||||
|
||||
HStack (alignment: .bottom){
|
||||
|
||||
VStack {
|
||||
Text(user.longName ?? "Unknown").font(.headline)
|
||||
}
|
||||
|
||||
VStack {
|
||||
if lastMessageDay == currentDay {
|
||||
|
||||
Text(lastMessageTime, style: .time )
|
||||
.font(.caption)
|
||||
.foregroundColor(.gray)
|
||||
|
||||
} else if ( lastMessageDay == (currentDay - 1)) {
|
||||
|
||||
Text("Yesterday")
|
||||
.font(.callout)
|
||||
.foregroundColor(.gray)
|
||||
|
||||
} else if ( lastMessageDay < (currentDay - 1) && lastMessageDay > (currentDay - 5) ) {
|
||||
|
||||
Text(lastMessageTime, style: .date)
|
||||
|
||||
} else {
|
||||
|
||||
Text(lastMessageTime, style: .date)
|
||||
}
|
||||
}.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
}
|
||||
.listRowSeparator(.hidden).frame(height: 5)
|
||||
HStack (alignment: .top) {
|
||||
|
||||
Text(mostRecent.messagePayload ?? "EMPTY MESSSAGE")
|
||||
.frame(height: 60)
|
||||
.truncationMode(.tail)
|
||||
}
|
||||
}
|
||||
}.padding(10)
|
||||
} else {
|
||||
HStack {
|
||||
VStack {
|
||||
CircleText(text: user.shortName ?? "???", color: Color.blue)
|
||||
}
|
||||
VStack {
|
||||
|
||||
HStack{
|
||||
|
||||
VStack {
|
||||
Text(user.longName ?? "Unknown").font(.title3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.padding()
|
||||
}
|
||||
//NavigationLink(note.title, destination: NoteEditor(id: note.id))
|
||||
}
|
||||
.navigationTitle("Contacts")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ struct NodeDetail: View {
|
|||
}
|
||||
}.padding()
|
||||
|
||||
if node.positions?.count ?? 0 > 0 {
|
||||
if node.positions?.count ?? 0 > 1 {
|
||||
|
||||
Divider()
|
||||
|
||||
|
|
@ -193,52 +193,51 @@ struct NodeDetail: View {
|
|||
|
||||
ForEach(node.positions!.array as! [PositionEntity], id: \.self) { (mappin: PositionEntity) in
|
||||
|
||||
//if mappin.coordinate != nil {
|
||||
if mappin.coordinate != nil {
|
||||
|
||||
VStack {
|
||||
|
||||
HStack {
|
||||
|
||||
Image(systemName: "mappin.and.ellipse").foregroundColor(.accentColor) //.font(.subheadline)
|
||||
Text("Lat/Long:").font(.caption)
|
||||
Text("\(String(mappin.latitude ?? 0)) \(String(mappin.longitude ?? 0))")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
HStack {
|
||||
|
||||
Text("Altitude:")
|
||||
.font(.caption)
|
||||
|
||||
Text("\(String(mappin.altitude))m")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
Image(systemName: "mappin.and.ellipse").foregroundColor(.accentColor) //.font(.subheadline)
|
||||
Text("Lat/Long:").font(.caption)
|
||||
Text("\(String(mappin.latitude ?? 0)) \(String(mappin.longitude ?? 0))")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
|
||||
Text("Altitude:")
|
||||
.font(.caption)
|
||||
|
||||
Text("\(String(mappin.altitude))m")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
}
|
||||
HStack {
|
||||
|
||||
Image(systemName: "clock.badge.checkmark.fill")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.accentColor)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("Time:")
|
||||
.font(.caption)
|
||||
Text("\(mappin.time!, style: .date) \(mappin.time!, style: .time)")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
Divider()
|
||||
|
||||
Text("Battery").font(.caption).fixedSize()
|
||||
Text(String(mappin.batteryLevel) + "%")
|
||||
.font(.caption)
|
||||
.foregroundColor(.gray)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
}
|
||||
}
|
||||
HStack {
|
||||
|
||||
Image(systemName: "clock.badge.checkmark.fill")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.accentColor)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("Time:")
|
||||
.font(.caption)
|
||||
Text("\(mappin.time!, style: .date) \(mappin.time!, style: .time)")
|
||||
.foregroundColor(.gray)
|
||||
.font(.caption)
|
||||
Divider()
|
||||
|
||||
Text("Battery").font(.caption).fixedSize()
|
||||
Text(String(mappin.batteryLevel) + "%")
|
||||
.font(.caption)
|
||||
.foregroundColor(.gray)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
}
|
||||
}
|
||||
.padding(1)
|
||||
Divider()
|
||||
//}
|
||||
}
|
||||
}
|
||||
.padding(.bottom, 5) // Without some padding here there is a transparent contentview bug
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.navigationTitle(node.user!.longName ?? "Unknown")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue