mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Turn contacts list back on
This commit is contained in:
parent
7416676c69
commit
461db4275d
5 changed files with 437 additions and 437 deletions
|
|
@ -204,9 +204,9 @@ struct Connect: View {
|
|||
ZStack {
|
||||
|
||||
ConnectedDevice(
|
||||
bluetoothOn: bleManager.isSwitchedOn,
|
||||
deviceConnected: bleManager.connectedPeripheral != nil,
|
||||
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName :
|
||||
bluetoothOn: self.bleManager.isSwitchedOn,
|
||||
deviceConnected: self.bleManager.connectedPeripheral != nil,
|
||||
name: (bleManager.connectedPeripheral != nil) ? self.bleManager.connectedPeripheral.shortName :
|
||||
"???")
|
||||
}
|
||||
)
|
||||
|
|
@ -216,7 +216,7 @@ struct Connect: View {
|
|||
|
||||
self.bleManager.context = context
|
||||
|
||||
if bleManager.connectedPeripheral != nil && userSettings.preferredPeripheralId == bleManager.connectedPeripheral.peripheral.identifier.uuidString {
|
||||
if self.bleManager.connectedPeripheral != nil && userSettings.preferredPeripheralId == self.bleManager.connectedPeripheral.peripheral.identifier.uuidString {
|
||||
isPreferredRadio = true
|
||||
} else {
|
||||
isPreferredRadio = false
|
||||
|
|
|
|||
|
|
@ -41,13 +41,13 @@ struct ContentView: View {
|
|||
.symbolVariant(.none)
|
||||
}
|
||||
.tag(Tab.ble)
|
||||
// NodeList()
|
||||
// .tabItem {
|
||||
// Label("Nodes", systemImage: "flipphone")
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
// .symbolVariant(.none)
|
||||
// }
|
||||
// .tag(Tab.nodes)
|
||||
NodeList()
|
||||
.tabItem {
|
||||
Label("Nodes", systemImage: "flipphone")
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
.symbolVariant(.none)
|
||||
}
|
||||
.tag(Tab.nodes)
|
||||
NodeMap()
|
||||
.tabItem {
|
||||
Label("Mesh Map", systemImage: "map")
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ struct Contacts: View {
|
|||
let lastMessageDay = Calendar.current.dateComponents([.day], from: lastMessageTime).day ?? 0
|
||||
let currentDay = Calendar.current.dateComponents([.day], from: Date()).day ?? 0
|
||||
|
||||
if user.num == bleManager.broadcastNodeNum {//user.num != currentUserNum && (user.num == bleManager.broadcastNodeNum || mostRecentDM != nil) {
|
||||
if user.num != currentUserNum && (user.num == bleManager.broadcastNodeNum || mostRecentDM != nil) {
|
||||
|
||||
NavigationLink(destination: UserMessageList(user: user)
|
||||
.environment(\.managedObjectContext, self.context)) {
|
||||
|
|
@ -96,7 +96,7 @@ struct Contacts: View {
|
|||
}
|
||||
}
|
||||
|
||||
} else if false {// self.bleManager.connectedPeripheral == nil || ((self.bleManager.connectedPeripheral != nil ? self.bleManager.connectedPeripheral.num : 0) != user.num) {
|
||||
} else if self.bleManager.connectedPeripheral == nil || ((self.bleManager.connectedPeripheral != nil ? self.bleManager.connectedPeripheral.num : 0) != user.num) {
|
||||
|
||||
NavigationLink(destination: UserMessageList(user: user)) {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,298 +1,298 @@
|
|||
///*
|
||||
//Abstract:
|
||||
//A view showing the details for a node.
|
||||
//*/
|
||||
//
|
||||
//import SwiftUI
|
||||
//import MapKit
|
||||
//import CoreLocation
|
||||
//
|
||||
//struct NodeDetail: View {
|
||||
//
|
||||
// @Environment(\.managedObjectContext) var context
|
||||
// @EnvironmentObject var bleManager: BLEManager
|
||||
//
|
||||
// var node: NodeInfoEntity
|
||||
//
|
||||
// var body: some View {
|
||||
//
|
||||
// HStack {
|
||||
//
|
||||
// GeometryReader { bounds in
|
||||
//
|
||||
// VStack {
|
||||
//
|
||||
// if node.positions?.count ?? 0 > 0 {
|
||||
//
|
||||
// let mostRecent = node.positions?.lastObject as! PositionEntity
|
||||
//
|
||||
// if mostRecent.coordinate != nil {
|
||||
//
|
||||
// let nodeCoordinatePosition = CLLocationCoordinate2D(latitude: mostRecent.latitude!, longitude: mostRecent.longitude!)
|
||||
//
|
||||
// let regionBinding = Binding<MKCoordinateRegion>(
|
||||
// get: {
|
||||
// MKCoordinateRegion(center: nodeCoordinatePosition, span: MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005))
|
||||
// },
|
||||
// set: { _ in }
|
||||
// )
|
||||
// let annotations = [MapLocation(name: node.user!.shortName ?? "???", coordinate: mostRecent.coordinate!)]
|
||||
//
|
||||
// Map(coordinateRegion: regionBinding, showsUserLocation: true, userTrackingMode: .none, annotationItems: annotations) { location in
|
||||
// MapAnnotation(
|
||||
// coordinate: location.coordinate,
|
||||
// content: {
|
||||
// CircleText(text: node.user!.shortName ?? "???", color: .accentColor)
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
// .frame(idealWidth: bounds.size.width, maxHeight: bounds.size.height / 3)
|
||||
// } else {
|
||||
//
|
||||
// Image(node.user?.hwModel ?? "UNSET")
|
||||
// .resizable()
|
||||
// .aspectRatio(contentMode: .fit)
|
||||
// .frame(width: bounds.size.width, height: bounds.size.height / 2)
|
||||
// }
|
||||
// } else {
|
||||
//
|
||||
// Image(node.user?.hwModel ?? "UNSET")
|
||||
// .resizable()
|
||||
// .aspectRatio(contentMode: .fit)
|
||||
// .frame(width: bounds.size.width, height: bounds.size.height / 2)
|
||||
// }
|
||||
//
|
||||
// ScrollView {
|
||||
//
|
||||
// if node.lastHeard != nil {
|
||||
//
|
||||
// HStack {
|
||||
//
|
||||
// Image(systemName: "clock.badge.checkmark.fill")
|
||||
// .font(.title)
|
||||
// .foregroundColor(.accentColor)
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
// Text("Last Heard: \(node.lastHeard!, style: .relative) ago").font(.title3)
|
||||
// }
|
||||
// .padding()
|
||||
// Divider()
|
||||
// }
|
||||
//
|
||||
// HStack {
|
||||
//
|
||||
// VStack(alignment: .center) {
|
||||
// Text("AKA").font(.title2).fixedSize()
|
||||
// CircleText(text: node.user?.shortName ?? "???", color: .accentColor)
|
||||
// .offset(y: 10)
|
||||
// }
|
||||
// .padding(5)
|
||||
//
|
||||
// Divider()
|
||||
//
|
||||
// VStack {
|
||||
//
|
||||
// Image(node.user!.hwModel ?? "UNSET")
|
||||
// .resizable()
|
||||
// .frame(width: 50, height: 50)
|
||||
// .cornerRadius(5)
|
||||
//
|
||||
// Text(String(node.user!.hwModel ?? "UNSET"))
|
||||
// .font(.callout).fixedSize()
|
||||
// }
|
||||
// .padding(5)
|
||||
//
|
||||
// if node.snr > 0 {
|
||||
// Divider()
|
||||
// VStack(alignment: .center) {
|
||||
//
|
||||
// Image(systemName: "waveform.path")
|
||||
// .font(.title)
|
||||
// .foregroundColor(.accentColor)
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
// Text("SNR").font(.title2).fixedSize()
|
||||
// Text(String(node.snr))
|
||||
// .font(.title2)
|
||||
// .foregroundColor(.gray)
|
||||
// .fixedSize()
|
||||
// }
|
||||
// .padding(5)
|
||||
// }
|
||||
//
|
||||
// if node.positions!.count > 0 {
|
||||
//
|
||||
// let mostRecent = node.positions?.lastObject as! PositionEntity
|
||||
//
|
||||
// Divider()
|
||||
//
|
||||
// VStack(alignment: .center) {
|
||||
//
|
||||
// BatteryIcon(batteryLevel: mostRecent.batteryLevel, font: .title, color: .accentColor)
|
||||
// .padding(.bottom)
|
||||
// if mostRecent.batteryLevel > 0 {
|
||||
//
|
||||
// Text("Battery")
|
||||
// .font(.title2)
|
||||
// .fixedSize()
|
||||
// .textCase(.uppercase)
|
||||
// Text(String(mostRecent.batteryLevel) + "%")
|
||||
// .font(.title2)
|
||||
// .foregroundColor(.gray)
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
// } else {
|
||||
//
|
||||
// Text("Powered")
|
||||
// .font(.callout)
|
||||
// .fixedSize()
|
||||
// .textCase(.uppercase)
|
||||
// }
|
||||
// }
|
||||
// .padding(5)
|
||||
// }
|
||||
// }
|
||||
// .padding(4)
|
||||
//
|
||||
// Divider()
|
||||
//
|
||||
// HStack(alignment: .center) {
|
||||
// VStack {
|
||||
// HStack {
|
||||
// Image(systemName: "person")
|
||||
// .font(.title2)
|
||||
// .foregroundColor(.accentColor)
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
// Text("User Id:").font(.title2)
|
||||
// }
|
||||
// Text(node.user?.userId ?? "??????").font(.title3).foregroundColor(.gray)
|
||||
// }
|
||||
// Divider()
|
||||
// VStack {
|
||||
// HStack {
|
||||
// Image(systemName: "number")
|
||||
// .font(.title2)
|
||||
// .foregroundColor(.accentColor)
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
// Text("Node Number:").font(.title2)
|
||||
// }
|
||||
// Text(String(node.num)).font(.title3).foregroundColor(.gray)
|
||||
// }
|
||||
// }
|
||||
// .padding(5)
|
||||
// Divider()
|
||||
// HStack {
|
||||
// Image(systemName: "globe")
|
||||
// .font(.headline)
|
||||
// .foregroundColor(.accentColor)
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
// Text("MAC Address: ")
|
||||
// Text(String(node.user?.macaddr?.macAddressString ?? "not a valid mac address")).foregroundColor(.gray)
|
||||
// }
|
||||
// .padding()
|
||||
//
|
||||
// if node.positions?.count ?? 0 > 1 {
|
||||
//
|
||||
// Divider()
|
||||
//
|
||||
// HStack {
|
||||
//
|
||||
// Image(systemName: "location.circle.fill")
|
||||
// .font(.title)
|
||||
// .foregroundColor(.accentColor)
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
// Text("Location History").font(.title2)
|
||||
// }
|
||||
// .padding()
|
||||
//
|
||||
// Divider()
|
||||
//
|
||||
// ForEach(node.positions!.array as! [PositionEntity], id: \.self) { (mappin: PositionEntity) in
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// Image(systemName: "arrow.up.arrow.down.circle")
|
||||
// .font(.subheadline)
|
||||
// .foregroundColor(.accentColor)
|
||||
// .symbolRenderingMode(.hierarchical)
|
||||
//
|
||||
// Text("Alt:")
|
||||
// .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()
|
||||
//
|
||||
// HStack {
|
||||
//
|
||||
// BatteryIcon(batteryLevel: mappin.batteryLevel, font: .subheadline, color: .accentColor)
|
||||
//
|
||||
// if mappin.batteryLevel > 0 {
|
||||
//
|
||||
// Text(String(mappin.batteryLevel) + "%")
|
||||
// .font(.caption2)
|
||||
// .foregroundColor(.gray)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .padding(1)
|
||||
// Divider()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }.ignoresSafeArea(.all, edges: [.leading, .trailing])
|
||||
// }
|
||||
// }
|
||||
// .navigationTitle(node.user!.longName ?? "Unknown")
|
||||
// .navigationBarTitleDisplayMode(.inline)
|
||||
// .navigationBarItems(trailing:
|
||||
//
|
||||
// ZStack {
|
||||
//
|
||||
// ConnectedDevice(
|
||||
// bluetoothOn: bleManager.isSwitchedOn,
|
||||
// deviceConnected: bleManager.connectedPeripheral != nil,
|
||||
// name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???")
|
||||
// }
|
||||
// )
|
||||
// .onAppear(perform: {
|
||||
//
|
||||
// self.bleManager.context = context
|
||||
//
|
||||
// })
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//struct NodeInfoEntityDetail_Previews: PreviewProvider {
|
||||
//
|
||||
// static let bleManager = BLEManager()
|
||||
//
|
||||
// static var previews: some View {
|
||||
// Group {
|
||||
//
|
||||
// // NodeDetail(node: node)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
/*
|
||||
Abstract:
|
||||
A view showing the details for a node.
|
||||
*/
|
||||
|
||||
import SwiftUI
|
||||
import MapKit
|
||||
import CoreLocation
|
||||
|
||||
struct NodeDetail: View {
|
||||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
|
||||
var node: NodeInfoEntity
|
||||
|
||||
var body: some View {
|
||||
|
||||
HStack {
|
||||
|
||||
GeometryReader { bounds in
|
||||
|
||||
VStack {
|
||||
|
||||
if node.positions?.count ?? 0 > 0 {
|
||||
|
||||
let mostRecent = node.positions?.lastObject as! PositionEntity
|
||||
|
||||
if mostRecent.coordinate != nil {
|
||||
|
||||
let nodeCoordinatePosition = CLLocationCoordinate2D(latitude: mostRecent.latitude!, longitude: mostRecent.longitude!)
|
||||
|
||||
let regionBinding = Binding<MKCoordinateRegion>(
|
||||
get: {
|
||||
MKCoordinateRegion(center: nodeCoordinatePosition, span: MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005))
|
||||
},
|
||||
set: { _ in }
|
||||
)
|
||||
let annotations = [MapLocation(name: node.user!.shortName ?? "???", coordinate: mostRecent.coordinate!)]
|
||||
|
||||
Map(coordinateRegion: regionBinding, showsUserLocation: true, userTrackingMode: .none, annotationItems: annotations) { location in
|
||||
MapAnnotation(
|
||||
coordinate: location.coordinate,
|
||||
content: {
|
||||
CircleText(text: node.user!.shortName ?? "???", color: .accentColor)
|
||||
}
|
||||
)
|
||||
}
|
||||
.frame(idealWidth: bounds.size.width, maxHeight: bounds.size.height / 3)
|
||||
} else {
|
||||
|
||||
Image(node.user?.hwModel ?? "UNSET")
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: bounds.size.width, height: bounds.size.height / 2)
|
||||
}
|
||||
} else {
|
||||
|
||||
Image(node.user?.hwModel ?? "UNSET")
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: bounds.size.width, height: bounds.size.height / 2)
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
|
||||
if node.lastHeard != nil {
|
||||
|
||||
HStack {
|
||||
|
||||
Image(systemName: "clock.badge.checkmark.fill")
|
||||
.font(.title)
|
||||
.foregroundColor(.accentColor)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("Last Heard: \(node.lastHeard!, style: .relative) ago").font(.title3)
|
||||
}
|
||||
.padding()
|
||||
Divider()
|
||||
}
|
||||
|
||||
HStack {
|
||||
|
||||
VStack(alignment: .center) {
|
||||
Text("AKA").font(.title2).fixedSize()
|
||||
CircleText(text: node.user?.shortName ?? "???", color: .accentColor)
|
||||
.offset(y: 10)
|
||||
}
|
||||
.padding(5)
|
||||
|
||||
Divider()
|
||||
|
||||
VStack {
|
||||
|
||||
Image(node.user!.hwModel ?? "UNSET")
|
||||
.resizable()
|
||||
.frame(width: 50, height: 50)
|
||||
.cornerRadius(5)
|
||||
|
||||
Text(String(node.user!.hwModel ?? "UNSET"))
|
||||
.font(.callout).fixedSize()
|
||||
}
|
||||
.padding(5)
|
||||
|
||||
if node.snr > 0 {
|
||||
Divider()
|
||||
VStack(alignment: .center) {
|
||||
|
||||
Image(systemName: "waveform.path")
|
||||
.font(.title)
|
||||
.foregroundColor(.accentColor)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("SNR").font(.title2).fixedSize()
|
||||
Text(String(node.snr))
|
||||
.font(.title2)
|
||||
.foregroundColor(.gray)
|
||||
.fixedSize()
|
||||
}
|
||||
.padding(5)
|
||||
}
|
||||
|
||||
if node.positions!.count > 0 {
|
||||
|
||||
let mostRecent = node.positions?.lastObject as! PositionEntity
|
||||
|
||||
Divider()
|
||||
|
||||
VStack(alignment: .center) {
|
||||
|
||||
BatteryIcon(batteryLevel: mostRecent.batteryLevel, font: .title, color: .accentColor)
|
||||
.padding(.bottom)
|
||||
if mostRecent.batteryLevel > 0 {
|
||||
|
||||
Text("Battery")
|
||||
.font(.title2)
|
||||
.fixedSize()
|
||||
.textCase(.uppercase)
|
||||
Text(String(mostRecent.batteryLevel) + "%")
|
||||
.font(.title2)
|
||||
.foregroundColor(.gray)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
} else {
|
||||
|
||||
Text("Powered")
|
||||
.font(.callout)
|
||||
.fixedSize()
|
||||
.textCase(.uppercase)
|
||||
}
|
||||
}
|
||||
.padding(5)
|
||||
}
|
||||
}
|
||||
.padding(4)
|
||||
|
||||
Divider()
|
||||
|
||||
HStack(alignment: .center) {
|
||||
VStack {
|
||||
HStack {
|
||||
Image(systemName: "person")
|
||||
.font(.title2)
|
||||
.foregroundColor(.accentColor)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("User Id:").font(.title2)
|
||||
}
|
||||
Text(node.user?.userId ?? "??????").font(.title3).foregroundColor(.gray)
|
||||
}
|
||||
Divider()
|
||||
VStack {
|
||||
HStack {
|
||||
Image(systemName: "number")
|
||||
.font(.title2)
|
||||
.foregroundColor(.accentColor)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("Node Number:").font(.title2)
|
||||
}
|
||||
Text(String(node.num)).font(.title3).foregroundColor(.gray)
|
||||
}
|
||||
}
|
||||
.padding(5)
|
||||
Divider()
|
||||
HStack {
|
||||
Image(systemName: "globe")
|
||||
.font(.headline)
|
||||
.foregroundColor(.accentColor)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("MAC Address: ")
|
||||
Text(String(node.user?.macaddr?.macAddressString ?? "not a valid mac address")).foregroundColor(.gray)
|
||||
}
|
||||
.padding()
|
||||
|
||||
if node.positions?.count ?? 0 > 1 {
|
||||
|
||||
Divider()
|
||||
|
||||
HStack {
|
||||
|
||||
Image(systemName: "location.circle.fill")
|
||||
.font(.title)
|
||||
.foregroundColor(.accentColor)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
Text("Location History").font(.title2)
|
||||
}
|
||||
.padding()
|
||||
|
||||
Divider()
|
||||
|
||||
ForEach(node.positions!.array as! [PositionEntity], id: \.self) { (mappin: PositionEntity) in
|
||||
|
||||
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)
|
||||
|
||||
Image(systemName: "arrow.up.arrow.down.circle")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.accentColor)
|
||||
.symbolRenderingMode(.hierarchical)
|
||||
|
||||
Text("Alt:")
|
||||
.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()
|
||||
|
||||
HStack {
|
||||
|
||||
BatteryIcon(batteryLevel: mappin.batteryLevel, font: .subheadline, color: .accentColor)
|
||||
|
||||
if mappin.batteryLevel > 0 {
|
||||
|
||||
Text(String(mappin.batteryLevel) + "%")
|
||||
.font(.caption2)
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(1)
|
||||
Divider()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.ignoresSafeArea(.all, edges: [.leading, .trailing])
|
||||
}
|
||||
}
|
||||
.navigationTitle(node.user!.longName ?? "Unknown")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.navigationBarItems(trailing:
|
||||
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(
|
||||
bluetoothOn: bleManager.isSwitchedOn,
|
||||
deviceConnected: bleManager.connectedPeripheral != nil,
|
||||
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???")
|
||||
}
|
||||
)
|
||||
.onAppear(perform: {
|
||||
|
||||
self.bleManager.context = context
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct NodeInfoEntityDetail_Previews: PreviewProvider {
|
||||
|
||||
static let bleManager = BLEManager()
|
||||
|
||||
static var previews: some View {
|
||||
Group {
|
||||
|
||||
// NodeDetail(node: node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,129 +1,129 @@
|
|||
////
|
||||
//// NodeList.swift
|
||||
//// MeshtasticClient
|
||||
////
|
||||
//// Created by Garth Vander Houwen on 8/7/21.
|
||||
////
|
||||
//
|
||||
//// Abstract:
|
||||
//// A view showing a list of devices that have been seen on the mesh network from the perspective of the connected device.
|
||||
// NodeList.swift
|
||||
// MeshtasticClient
|
||||
//
|
||||
//import SwiftUI
|
||||
// Created by Garth Vander Houwen on 8/7/21.
|
||||
//
|
||||
//struct NodeList: View {
|
||||
//
|
||||
// @Environment(\.managedObjectContext) var context
|
||||
// @EnvironmentObject var bleManager: BLEManager
|
||||
//
|
||||
// @FetchRequest(
|
||||
// sortDescriptors: [NSSortDescriptor(key: "lastHeard", ascending: false)],
|
||||
// animation: .default)
|
||||
//
|
||||
// private var nodes: FetchedResults<NodeInfoEntity>
|
||||
//
|
||||
// @State private var selection: String?
|
||||
//
|
||||
// var body: some View {
|
||||
//
|
||||
// NavigationView {
|
||||
//
|
||||
// List {
|
||||
//
|
||||
// if nodes.count == 0 {
|
||||
//
|
||||
// Text("Scan for Radios").font(.largeTitle)
|
||||
// Text("No LoRa Mesh Nodes Found").font(.title2)
|
||||
// Text("Go to the bluetooth section in the bottom right menu and click the Start Scanning button to scan for nearby radios and find your Meshtastic device. Make sure your device is powered on and near your phone or tablet.")
|
||||
// .font(.body)
|
||||
// Text("Once the device shows under Available Devices touch the device you want to connect to and it will pull node information over BLE and populate the node list and mesh map in the Meshtastic app.")
|
||||
// Text("Views with bluetooth functionality will show an indicator in the upper right hand corner show if bluetooth is on, and if a device is connected.")
|
||||
// .listRowSeparator(.visible)
|
||||
//
|
||||
// } else {
|
||||
// ForEach( nodes ) { node in
|
||||
//
|
||||
// let index = nodes.firstIndex(where: { $0.id == node.id })
|
||||
//
|
||||
// NavigationLink(destination: NodeDetail(node: node), tag: String(index!), selection: $selection) {
|
||||
//
|
||||
// let connected: Bool = (bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.name == node.bleName)
|
||||
//
|
||||
// VStack(alignment: .leading) {
|
||||
//
|
||||
// HStack {
|
||||
//
|
||||
// CircleText(text: node.user?.shortName ?? "???", color: Color.accentColor).offset(y: 1).padding(.trailing, 5)
|
||||
// .offset(x: -15)
|
||||
//
|
||||
// if UIDevice.current.userInterfaceIdiom == .pad { Text(node.user?.longName ?? "Unknown").font(.headline)
|
||||
// .offset(x: -15)
|
||||
// } else {
|
||||
// Text(node.user?.longName ?? "Unknown").font(.title).offset(x: -15)
|
||||
// }
|
||||
// }
|
||||
// .padding(.bottom, 10)
|
||||
//
|
||||
// if connected {
|
||||
// HStack(alignment: .bottom) {
|
||||
//
|
||||
// Image(systemName: "repeat.circle.fill").font(.title3)
|
||||
// .foregroundColor(.accentColor).symbolRenderingMode(.hierarchical)
|
||||
// Text("Currently Connected").font(.title3).foregroundColor(Color.accentColor)
|
||||
// }
|
||||
// Spacer()
|
||||
// }
|
||||
//
|
||||
// HStack(alignment: .bottom) {
|
||||
//
|
||||
// Image(systemName: "clock.badge.checkmark.fill").font(.title3).foregroundColor(.accentColor).symbolRenderingMode(.hierarchical)
|
||||
//
|
||||
// if node.lastHeard != nil {
|
||||
// Text("Last Heard: \(node.lastHeard!, style: .relative) ago").font(.subheadline).foregroundColor(.gray)
|
||||
// } else {
|
||||
// Text("Last Heard: Unknown").font(.subheadline).foregroundColor(.gray)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .padding([.leading, .top, .bottom])
|
||||
// }
|
||||
// .swipeActions {
|
||||
//
|
||||
// Button {
|
||||
//
|
||||
// context.delete(node)
|
||||
//
|
||||
// do {
|
||||
//
|
||||
// try context.save()
|
||||
// print("Successfully Deleted NodeInfoEntiy: \(node.num)")
|
||||
//
|
||||
// } catch {
|
||||
//
|
||||
// print("Failed to save context after deleting NodeInfoEntity Num: \(node.num)")
|
||||
// }
|
||||
//
|
||||
// } label: {
|
||||
//
|
||||
// Label("Delete from app", systemImage: "trash")
|
||||
// }
|
||||
// .tint(.red)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .navigationTitle("All Nodes")
|
||||
// .onAppear {
|
||||
// // self.nodes.returnsObjectsAsFaults = false
|
||||
// self.bleManager.context = context
|
||||
//
|
||||
// if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
// if nodes.count > 0 {
|
||||
// selection = "0"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// .ignoresSafeArea(.all, edges: [.leading, .trailing])
|
||||
// .navigationViewStyle(DoubleColumnNavigationViewStyle())
|
||||
// }
|
||||
//}
|
||||
|
||||
// Abstract:
|
||||
// A view showing a list of devices that have been seen on the mesh network from the perspective of the connected device.
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct NodeList: View {
|
||||
|
||||
@Environment(\.managedObjectContext) var context
|
||||
@EnvironmentObject var bleManager: BLEManager
|
||||
|
||||
@FetchRequest(
|
||||
sortDescriptors: [NSSortDescriptor(key: "lastHeard", ascending: false)],
|
||||
animation: .default)
|
||||
|
||||
private var nodes: FetchedResults<NodeInfoEntity>
|
||||
|
||||
@State private var selection: String?
|
||||
|
||||
var body: some View {
|
||||
|
||||
NavigationView {
|
||||
|
||||
List {
|
||||
|
||||
if nodes.count == 0 {
|
||||
|
||||
Text("Scan for Radios").font(.largeTitle)
|
||||
Text("No LoRa Mesh Nodes Found").font(.title2)
|
||||
Text("Go to the bluetooth section in the bottom right menu and click the Start Scanning button to scan for nearby radios and find your Meshtastic device. Make sure your device is powered on and near your phone or tablet.")
|
||||
.font(.body)
|
||||
Text("Once the device shows under Available Devices touch the device you want to connect to and it will pull node information over BLE and populate the node list and mesh map in the Meshtastic app.")
|
||||
Text("Views with bluetooth functionality will show an indicator in the upper right hand corner show if bluetooth is on, and if a device is connected.")
|
||||
.listRowSeparator(.visible)
|
||||
|
||||
} else {
|
||||
ForEach( nodes ) { node in
|
||||
|
||||
let index = nodes.firstIndex(where: { $0.id == node.id })
|
||||
|
||||
NavigationLink(destination: NodeDetail(node: node), tag: String(index!), selection: $selection) {
|
||||
|
||||
let connected: Bool = (bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.name == node.bleName)
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
|
||||
HStack {
|
||||
|
||||
CircleText(text: node.user?.shortName ?? "???", color: Color.accentColor).offset(y: 1).padding(.trailing, 5)
|
||||
.offset(x: -15)
|
||||
|
||||
if UIDevice.current.userInterfaceIdiom == .pad { Text(node.user?.longName ?? "Unknown").font(.headline)
|
||||
.offset(x: -15)
|
||||
} else {
|
||||
Text(node.user?.longName ?? "Unknown").font(.title).offset(x: -15)
|
||||
}
|
||||
}
|
||||
.padding(.bottom, 10)
|
||||
|
||||
if connected {
|
||||
HStack(alignment: .bottom) {
|
||||
|
||||
Image(systemName: "repeat.circle.fill").font(.title3)
|
||||
.foregroundColor(.accentColor).symbolRenderingMode(.hierarchical)
|
||||
Text("Currently Connected").font(.title3).foregroundColor(Color.accentColor)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
|
||||
HStack(alignment: .bottom) {
|
||||
|
||||
Image(systemName: "clock.badge.checkmark.fill").font(.title3).foregroundColor(.accentColor).symbolRenderingMode(.hierarchical)
|
||||
|
||||
if node.lastHeard != nil {
|
||||
Text("Last Heard: \(node.lastHeard!, style: .relative) ago").font(.subheadline).foregroundColor(.gray)
|
||||
} else {
|
||||
Text("Last Heard: Unknown").font(.subheadline).foregroundColor(.gray)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding([.leading, .top, .bottom])
|
||||
}
|
||||
.swipeActions {
|
||||
|
||||
Button {
|
||||
|
||||
context.delete(node)
|
||||
|
||||
do {
|
||||
|
||||
try context.save()
|
||||
print("Successfully Deleted NodeInfoEntiy: \(node.num)")
|
||||
|
||||
} catch {
|
||||
|
||||
print("Failed to save context after deleting NodeInfoEntity Num: \(node.num)")
|
||||
}
|
||||
|
||||
} label: {
|
||||
|
||||
Label("Delete from app", systemImage: "trash")
|
||||
}
|
||||
.tint(.red)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.navigationTitle("All Nodes")
|
||||
.onAppear {
|
||||
// self.nodes.returnsObjectsAsFaults = false
|
||||
self.bleManager.context = context
|
||||
|
||||
if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
if nodes.count > 0 {
|
||||
selection = "0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.ignoresSafeArea(.all, edges: [.leading, .trailing])
|
||||
.navigationViewStyle(DoubleColumnNavigationViewStyle())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue