Create dedicated data layer types for querying and updating CoreData

This commit is contained in:
Blake McAnally 2024-07-10 16:03:38 -05:00
parent 3a248b6121
commit b011cbde42
52 changed files with 2963 additions and 3035 deletions

View file

@ -45,6 +45,7 @@ disabled_rules: # rule identifiers to exclude from running
- operator_whitespace
- multiple_closures_with_trailing_closure
- todo
- trailing_whitespace
# TODO: should review
nesting:

View file

@ -67,7 +67,7 @@
DD3CC6BC28E366DF00FA9159 /* Meshtastic.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DD3CC6BA28E366DF00FA9159 /* Meshtastic.xcdatamodeld */; };
DD3CC6BE28E4CD9800FA9159 /* BatteryGauge.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3CC6BD28E4CD9800FA9159 /* BatteryGauge.swift */; };
DD3CC6C028E7A60700FA9159 /* MessagingEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3CC6BF28E7A60700FA9159 /* MessagingEnums.swift */; };
DD3CC6C228EB9D4900FA9159 /* UpdateCoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3CC6C128EB9D4900FA9159 /* UpdateCoreData.swift */; };
DD3CC6C228EB9D4900FA9159 /* UpdateCoreDataController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3CC6C128EB9D4900FA9159 /* UpdateCoreDataController.swift */; };
DD41582628582E9B009B0E59 /* DeviceConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD41582528582E9B009B0E59 /* DeviceConfig.swift */; };
DD415828285859C4009B0E59 /* TelemetryConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD415827285859C4009B0E59 /* TelemetryConfig.swift */; };
DD41582A28585C32009B0E59 /* RangeTestConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD41582928585C32009B0E59 /* RangeTestConfig.swift */; };
@ -109,7 +109,7 @@
DD964FBF296E76EF007C176F /* WaypointFormMapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FBE296E76EF007C176F /* WaypointFormMapKit.swift */; };
DD964FC2297272AE007C176F /* WaypointEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FC1297272AE007C176F /* WaypointEntityExtension.swift */; };
DD964FC42974767D007C176F /* MapViewFitExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FC32974767D007C176F /* MapViewFitExtension.swift */; };
DD964FC62975DBFD007C176F /* QueryCoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FC52975DBFD007C176F /* QueryCoreData.swift */; };
DD964FC62975DBFD007C176F /* QueryCoreDataController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FC52975DBFD007C176F /* QueryCoreDataController.swift */; };
DD97E96628EFD9820056DDA4 /* MeshtasticLogo.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD97E96528EFD9820056DDA4 /* MeshtasticLogo.swift */; };
DD97E96828EFE9A00056DDA4 /* About.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD97E96728EFE9A00056DDA4 /* About.swift */; };
DD994B69295F88B60013760A /* IntervalEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD994B68295F88B60013760A /* IntervalEnums.swift */; };
@ -292,7 +292,7 @@
DD3CC6BB28E366DF00FA9159 /* MeshtasticDataModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModel.xcdatamodel; sourceTree = "<group>"; };
DD3CC6BD28E4CD9800FA9159 /* BatteryGauge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryGauge.swift; sourceTree = "<group>"; };
DD3CC6BF28E7A60700FA9159 /* MessagingEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagingEnums.swift; sourceTree = "<group>"; };
DD3CC6C128EB9D4900FA9159 /* UpdateCoreData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateCoreData.swift; sourceTree = "<group>"; };
DD3CC6C128EB9D4900FA9159 /* UpdateCoreDataController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateCoreDataController.swift; sourceTree = "<group>"; };
DD3D17DC2C3D7B1400561584 /* MeshtasticDataModelV 39.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 39.xcdatamodel"; sourceTree = "<group>"; };
DD41582528582E9B009B0E59 /* DeviceConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceConfig.swift; sourceTree = "<group>"; };
DD415827285859C4009B0E59 /* TelemetryConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelemetryConfig.swift; sourceTree = "<group>"; };
@ -344,7 +344,7 @@
DD964FC029724F6D007C176F /* MeshtasticDataModelV6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV6.xcdatamodel; sourceTree = "<group>"; };
DD964FC1297272AE007C176F /* WaypointEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaypointEntityExtension.swift; sourceTree = "<group>"; };
DD964FC32974767D007C176F /* MapViewFitExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewFitExtension.swift; sourceTree = "<group>"; };
DD964FC52975DBFD007C176F /* QueryCoreData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryCoreData.swift; sourceTree = "<group>"; };
DD964FC52975DBFD007C176F /* QueryCoreDataController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryCoreDataController.swift; sourceTree = "<group>"; };
DD9681A22BBB22BE00FD2C47 /* MeshtasticDataModelV32.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV32.xcdatamodel; sourceTree = "<group>"; };
DD97E96528EFD9820056DDA4 /* MeshtasticLogo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticLogo.swift; sourceTree = "<group>"; };
DD97E96728EFE9A00056DDA4 /* About.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = About.swift; sourceTree = "<group>"; };
@ -869,8 +869,8 @@
isa = PBXGroup;
children = (
DDC4D567275499A500A4208E /* Persistence.swift */,
DD964FC52975DBFD007C176F /* QueryCoreData.swift */,
DD3CC6C128EB9D4900FA9159 /* UpdateCoreData.swift */,
DD964FC52975DBFD007C176F /* QueryCoreDataController.swift */,
DD3CC6C128EB9D4900FA9159 /* UpdateCoreDataController.swift */,
);
path = Persistence;
sourceTree = "<group>";
@ -1188,7 +1188,7 @@
DD33DB622B3D27C7003E1EA0 /* FirmwareApi.swift in Sources */,
DD3CC6B528E33FD100FA9159 /* ShareChannels.swift in Sources */,
DD1BF2F92776FE2E008C8D2F /* UserMessageList.swift in Sources */,
DD3CC6C228EB9D4900FA9159 /* UpdateCoreData.swift in Sources */,
DD3CC6C228EB9D4900FA9159 /* UpdateCoreDataController.swift in Sources */,
DDE0F7C5295F77B700B8AAB3 /* AppSettingsEnums.swift in Sources */,
DDB6ABE628B1406100384BA1 /* LoraConfigEnums.swift in Sources */,
DDB8F4142A9EE5F000230ECE /* ChannelList.swift in Sources */,
@ -1223,7 +1223,7 @@
DDD5BB092C285DDC007E03CA /* AppLog.swift in Sources */,
DD8ED9C8289CE4B900B3B0AB /* RoutingError.swift in Sources */,
DDC1B81A2AB5377B00C71E39 /* MessagesTips.swift in Sources */,
DD964FC62975DBFD007C176F /* QueryCoreData.swift in Sources */,
DD964FC62975DBFD007C176F /* QueryCoreDataController.swift in Sources */,
DDB75A112A059258006ED576 /* Url.swift in Sources */,
DDAD49ED2AFB39DC00B4425D /* MeshMap.swift in Sources */,
DD8169FB271F1F3A00F4AB02 /* MeshLog.swift in Sources */,

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -11,9 +11,20 @@ import TipKit
@main
struct MeshtasticAppleApp: App {
@UIApplicationDelegateAdaptor(MeshtasticAppDelegate.self) var appDelegate
let persistenceController = PersistenceController.shared
@ObservedObject private var bleManager: BLEManager = BLEManager.shared
@UIApplicationDelegateAdaptor(MeshtasticAppDelegate.self)
var appDelegate
@ObservedObject
var bleManager: BLEManager
@ObservedObject
var persistenceController: PersistenceController
@ObservedObject
var updateCoreDataController: UpdateCoreDataController
@ObservedObject
var queryCoreDataController: QueryCoreDataController
@Environment(\.scenePhase) var scenePhase
@ -23,10 +34,29 @@ struct MeshtasticAppleApp: App {
@State var addChannels = false
@StateObject var appState = AppState.shared
init() {
let persistenceController = PersistenceController()
let backgroundContext = persistenceController.container.newBackgroundContext()
let updateCoreDataController = UpdateCoreDataController(context: backgroundContext)
let queryCoreDataController = QueryCoreDataController(context: persistenceController.container.viewContext)
self.persistenceController = persistenceController
self.updateCoreDataController = updateCoreDataController
self.queryCoreDataController = queryCoreDataController
self.bleManager = BLEManager(
context: persistenceController.container.viewContext,
updateCoreDataController: updateCoreDataController,
queryCoreDataController: queryCoreDataController
)
}
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.environmentObject(persistenceController)
.environmentObject(updateCoreDataController)
.environmentObject(queryCoreDataController)
.environmentObject(bleManager)
.sheet(isPresented: $saveChannels) {
SaveChannelQRCode(channelSetLink: channelSettings ?? "Empty Channel URL", addChannels: addChannels, bleManager: bleManager)
@ -41,7 +71,7 @@ struct MeshtasticAppleApp: App {
if (self.incomingUrl?.absoluteString.lowercased().contains("meshtastic.org/e/#")) != nil {
if let components = self.incomingUrl?.absoluteString.components(separatedBy: "#") {
self.addChannels = Bool(self.incomingUrl?["add"] ?? "false") ?? false
if ((self.incomingUrl?.absoluteString.lowercased().contains("?")) != nil) {
if (self.incomingUrl?.absoluteString.lowercased().contains("?")) != nil {
guard let cs = components.last!.components(separatedBy: "?").first else {
return
}

View file

@ -8,9 +8,7 @@
import CoreData
import OSLog
class PersistenceController {
static let shared = PersistenceController()
class PersistenceController: ObservableObject {
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: false)
@ -72,6 +70,29 @@ class PersistenceController {
Logger.data.error("Failed to destroy CoreData database, delete the app and re-install to clear data. Attempted to clear persistent store: \(error.localizedDescription)")
}
}
public func clearCoreDataDatabase(context: NSManagedObjectContext, includeRoutes: Bool) {
for i in 0...container.managedObjectModel.entities.count-1 {
let entity = container.managedObjectModel.entities[i]
let query = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!)
var deleteRequest = NSBatchDeleteRequest(fetchRequest: query)
let entityName = entity.name ?? "UNK"
if includeRoutes {
deleteRequest = NSBatchDeleteRequest(fetchRequest: query)
} else if !includeRoutes {
if !(entityName.contains("RouteEntity") || entityName.contains("LocationEntity")) {
deleteRequest = NSBatchDeleteRequest(fetchRequest: query)
}
}
do {
try context.executeAndMergeChanges(using: deleteRequest)
} catch {
Logger.data.error("\(error.localizedDescription)")
}
}
}
}
extension NSManagedObjectContext {
@ -103,40 +124,7 @@ extension NSPersistentContainer {
case invalidSource(String)
}
/// Restore a persistent store for a URL `backupURL`.
/// **Be very careful with this**. To restore a persistent store, the current persistent store must be removed from the container. When that happens, **all currently loaded Core Data objects** will become invalid. Using them after restoring will cause your app to crash. When calling this method you **must** ensure that you do not continue to use any previously fetched managed objects or existing fetched results controllers. **If this method does not throw, that does not mean your app is safe.** You need to take extra steps to prevent crashes. The details vary depending on the nature of your app.
/// - Parameter backupURL: A file URL containing backup copies of all currently loaded persistent stores.
/// - Throws: `CopyPersistentStoreError` in various situations.
/// - Returns: Nothing. If no errors are thrown, the restore is complete.
// func restorePersistentStore(from backupURL: URL) throws -> Void {
// guard backupURL.isFileURL else {
// throw CopyPersistentStoreErrors.invalidSource("Backup URL must be a file URL")
// }
//
// for persistentStoreDescription in persistentStoreDescriptions {
// guard let loadedStoreURL = persistentStoreDescription.url else {
// continue
// }
// guard FileManager.default.fileExists(atPath: backupURL.path) else {
// throw CopyPersistentStoreErrors.invalidSource("Missing backup store for \(backupURL)")
// }
// do {
// let storeOptions = persistentStoreDescription.options
// let configurationName = persistentStoreDescription.configuration
// let storeType = persistentStoreDescription.type
//
// // Replace the current store with the backup copy. This has a side effect of removing the current store from the Core Data stack.
// // When restoring, it's necessary to use the current persistent store coordinator.
// try persistentStoreCoordinator.replacePersistentStore(at: loadedStoreURL, destinationOptions: storeOptions, withPersistentStoreFrom: backupURL, sourceOptions: storeOptions, ofType: storeType)
// // Add the persistent store at the same location we've been using, because it was removed in the previous step.
// try persistentStoreCoordinator.addPersistentStore(ofType: storeType, configurationName: configurationName, at: loadedStoreURL, options: storeOptions)
// } catch {
// throw CopyPersistentStoreErrors.copyStoreError("Could not restore: \(error.localizedDescription)")
// }
// }
// }
//
/// Restore backup persistent stores located in the directory referenced by `backupURL`.
/// Restore backup persistent stores located in the directory referenced by `backupURL`.
///
/// **Be very careful with this**. To restore a persistent store, the current persistent store must be removed from the container. When that happens, **all currently loaded Core Data objects** will become invalid. Using them after restoring will cause your app to crash. When calling this method you **must** ensure that you do not continue to use any previously fetched managed objects or existing fetched results controllers. **If this method does not throw, that does not mean your app is safe.** You need to take extra steps to prevent crashes. The details vary depending on the nature of your app.
/// - Parameter backupURL: A file URL containing backup copies of all currently loaded persistent stores.

View file

@ -1,91 +0,0 @@
//
// QueryCoreData.swift
// Meshtastic
//
// Created(c) Garth Vander Houwen 1/16/23.
//
import CoreData
public func getNodeInfo(id: Int64, context: NSManagedObjectContext) -> NodeInfoEntity? {
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(id))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest)
if fetchedNode.count == 1 {
return fetchedNode[0]
}
} catch {
return nil
}
return nil
}
public func getStoreAndForwardMessageIds(seconds: Int, context: NSManagedObjectContext) -> [UInt32] {
let time = seconds * -1
let fetchMessagesRequest = MessageEntity.fetchRequest()
let timeRange = Calendar.current.date(byAdding: .minute, value: time, to: Date())
let milleseconds = Int32(timeRange?.timeIntervalSince1970 ?? 0)
fetchMessagesRequest.predicate = NSPredicate(format: "receivedTimestamp >= %d", milleseconds)
do {
let fetchedMessages = try context.fetch(fetchMessagesRequest)
if fetchedMessages.count == 1 {
return fetchedMessages.map { UInt32($0.messageId) }
}
} catch {
return []
}
return []
}
public func getTraceRoute(id: Int64, context: NSManagedObjectContext) -> TraceRouteEntity? {
let fetchTraceRouteRequest = TraceRouteEntity.fetchRequest()
fetchTraceRouteRequest.predicate = NSPredicate(format: "id == %lld", Int64(id))
do {
let fetchedTraceRoute = try context.fetch(fetchTraceRouteRequest)
if fetchedTraceRoute.count == 1 {
return fetchedTraceRoute[0]
}
} catch {
return nil
}
return nil
}
public func getUser(id: Int64, context: NSManagedObjectContext) -> UserEntity {
let fetchUserRequest = UserEntity.fetchRequest()
fetchUserRequest.predicate = NSPredicate(format: "num == %lld", Int64(id))
do {
let fetchedUser = try context.fetch(fetchUserRequest)
if fetchedUser.count == 1 {
return fetchedUser[0]
}
} catch {
return UserEntity(context: context)
}
return UserEntity(context: context)
}
public func getWaypoint(id: Int64, context: NSManagedObjectContext) -> WaypointEntity {
let fetchWaypointRequest = WaypointEntity.fetchRequest()
fetchWaypointRequest.predicate = NSPredicate(format: "id == %lld", Int64(id))
do {
let fetchedWaypoint = try context.fetch(fetchWaypointRequest)
if fetchedWaypoint.count == 1 {
return fetchedWaypoint[0]
}
} catch {
return WaypointEntity(context: context)
}
return WaypointEntity(context: context)
}

View file

@ -0,0 +1,99 @@
//
// QueryCoreData.swift
// Meshtastic
//
// Created(c) Garth Vander Houwen 1/16/23.
//
import CoreData
class QueryCoreDataController: ObservableObject {
private let context: NSManagedObjectContext
init(context: NSManagedObjectContext) {
self.context = context
}
public func getNodeInfo(id: Int64) -> NodeInfoEntity? {
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(id))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest)
if fetchedNode.count == 1 {
return fetchedNode[0]
}
} catch {
return nil
}
return nil
}
public func getStoreAndForwardMessageIds(seconds: Int) -> [UInt32] {
let time = seconds * -1
let fetchMessagesRequest = MessageEntity.fetchRequest()
let timeRange = Calendar.current.date(byAdding: .minute, value: time, to: Date())
let milleseconds = Int32(timeRange?.timeIntervalSince1970 ?? 0)
fetchMessagesRequest.predicate = NSPredicate(format: "receivedTimestamp >= %d", milleseconds)
do {
let fetchedMessages = try context.fetch(fetchMessagesRequest)
if fetchedMessages.count == 1 {
return fetchedMessages.map { UInt32($0.messageId) }
}
} catch {
return []
}
return []
}
public func getTraceRoute(id: Int64) -> TraceRouteEntity? {
let fetchTraceRouteRequest = TraceRouteEntity.fetchRequest()
fetchTraceRouteRequest.predicate = NSPredicate(format: "id == %lld", Int64(id))
do {
let fetchedTraceRoute = try context.fetch(fetchTraceRouteRequest)
if fetchedTraceRoute.count == 1 {
return fetchedTraceRoute[0]
}
} catch {
return nil
}
return nil
}
public func getUser(id: Int64) -> UserEntity {
let fetchUserRequest = UserEntity.fetchRequest()
fetchUserRequest.predicate = NSPredicate(format: "num == %lld", Int64(id))
do {
let fetchedUser = try context.fetch(fetchUserRequest)
if fetchedUser.count == 1 {
return fetchedUser[0]
}
} catch {
return UserEntity(context: context)
}
return UserEntity(context: context)
}
public func getWaypoint(id: Int64) -> WaypointEntity {
let fetchWaypointRequest = WaypointEntity.fetchRequest()
fetchWaypointRequest.predicate = NSPredicate(format: "id == %lld", Int64(id))
do {
let fetchedWaypoint = try context.fetch(fetchWaypointRequest)
if fetchedWaypoint.count == 1 {
return fetchedWaypoint[0]
}
} catch {
return WaypointEntity(context: context)
}
return WaypointEntity(context: context)
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -226,7 +226,8 @@ struct Connect: View {
} catch {
Logger.data.error("🗂️ Core data backup copy error: \(error, privacy: .public)")
}
clearCoreDataDatabase(context: context, includeRoutes: false)
// TODO: fix-me
// clearCoreDataDatabase(context: context, includeRoutes: false)
}
UserDefaults.preferredPeripheralId = selectedPeripherialId
self.bleManager.connectTo(peripheral: peripheral.peripheral)
@ -323,11 +324,6 @@ struct Connect: View {
}
}
}
.onAppear(perform: {
if self.bleManager.context == nil {
self.bleManager.context = context
}
})
}
#if canImport(ActivityKit)
func startNodeActivity() {

View file

@ -13,6 +13,8 @@ import SwiftUI
struct WaypointFormMapKit: View {
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.managedObjectContext) private var context
@Environment(\.dismiss) private var dismiss
@State var coordinate: WaypointCoordinate
@FocusState private var iconIsFocused: Bool
@ -122,7 +124,7 @@ struct WaypointFormMapKit: View {
// Loading a waypoint from edit
if coordinate.waypointId > 0 {
newWaypoint.id = UInt32(coordinate.waypointId)
let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context!)
let waypoint = queryCoreDataController.getWaypoint(id: Int64(coordinate.waypointId))
newWaypoint.latitudeI = waypoint.latitudeI
newWaypoint.longitudeI = waypoint.longitudeI
} else {
@ -179,14 +181,15 @@ struct WaypointFormMapKit: View {
Menu {
Button("For me", action: {
let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context!)
bleManager.context!.delete(waypoint)
do {
try bleManager.context!.save()
} catch {
bleManager.context!.rollback()
}
dismiss() })
let waypoint = queryCoreDataController.getWaypoint(id: Int64(coordinate.waypointId))
context.delete(waypoint)
do {
try context.save()
} catch {
context.rollback()
}
dismiss()
})
Button("For everyone", action: {
var newWaypoint = Waypoint()
@ -230,7 +233,7 @@ struct WaypointFormMapKit: View {
}
.onAppear {
if coordinate.waypointId > 0 {
let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context!)
let waypoint = queryCoreDataController.getWaypoint(id: Int64(coordinate.waypointId))
name = waypoint.name ?? "Dropped Pin"
description = waypoint.longDescription ?? ""
icon = String(UnicodeScalar(Int(waypoint.icon)) ?? "📍")

View file

@ -14,6 +14,7 @@ struct ChannelList: View {
@StateObject var appState = AppState.shared
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var updateCoreDataController: UpdateCoreDataController
@State var node: NodeInfoEntity?
@ -140,7 +141,7 @@ struct ChannelList: View {
titleVisibility: .visible
) {
Button(role: .destructive) {
deleteChannelMessages(channel: channelSelection!, context: context)
updateCoreDataController.deleteChannelMessages(channel: channelSelection!)
context.refresh(myInfo, mergeChanges: true)
UIApplication.shared.applicationIconBadgeNumber = appState.unreadChannelMessages + appState.unreadDirectMessages
channelSelection = nil
@ -148,11 +149,6 @@ struct ChannelList: View {
Text("delete")
}
}
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
}
}
.padding([.top, .bottom])

View file

@ -131,9 +131,6 @@ struct ChannelMessageList: View {
.padding([.top])
.scrollDismissesKeyboard(.immediately)
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
if channel.allPrivateMessages.count > 0 {
scrollView.scrollTo(channel.allPrivateMessages.last!.messageId)
}

View file

@ -87,9 +87,6 @@ struct Messages: View {
}
}
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
if UserDefaults.preferredPeripheralId.count > 0 {
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(UserDefaults.preferredPeripheralNum))

View file

@ -17,6 +17,7 @@ struct UserList: View {
@StateObject var appState = AppState.shared
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var updateCoreDataController: UpdateCoreDataController
@State private var searchText = ""
@State private var viaLora = true
@State private var viaMqtt = true
@ -158,7 +159,7 @@ struct UserList: View {
titleVisibility: .visible
) {
Button(role: .destructive) {
deleteUserMessages(user: userSelection!, context: context)
updateCoreDataController.deleteUserMessages(user: userSelection!)
context.refresh(node!.user!, mergeChanges: true)
UIApplication.shared.applicationIconBadgeNumber = appState.unreadChannelMessages + appState.unreadDirectMessages
} label: {
@ -210,9 +211,6 @@ struct UserList: View {
userSelection = users.first(where: { $0.num == newUserNum })
}
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
searchUserList()
}
.safeAreaInset(edge: .bottom, alignment: .trailing) {

View file

@ -116,9 +116,6 @@ struct UserMessageList: View {
.padding([.top])
.scrollDismissesKeyboard(.immediately)
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
if user.messageList.count > 0 {
scrollView.scrollTo(user.messageList.last!.messageId)
}

View file

@ -124,11 +124,6 @@ struct DetectionSensorLog: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
.fileExporter(
isPresented: $isExporting,
document: CsvDocument(emptyCsv: exportString),

View file

@ -12,6 +12,7 @@ struct DeviceMetricsLog: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var updateCoreDataController: UpdateCoreDataController
@State private var isPresentingClearLogConfirm: Bool = false
@State var isExporting = false
@ -188,7 +189,7 @@ struct DeviceMetricsLog: View {
titleVisibility: .visible
) {
Button("device.metrics.delete", role: .destructive) {
if clearTelemetry(destNum: node.num, metricsType: 0, context: context) {
if updateCoreDataController.clearTelemetry(destNum: node.num, metricsType: 0) {
Logger.data.notice("Cleared Device Metrics for \(node.num)")
} else {
Logger.data.error("Clear Device Metrics Log Failed")
@ -222,11 +223,6 @@ struct DeviceMetricsLog: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
.fileExporter(
isPresented: $isExporting,
document: CsvDocument(emptyCsv: exportString),

View file

@ -12,6 +12,7 @@ struct EnvironmentMetricsLog: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var updateCoreDataController: UpdateCoreDataController
@State private var isPresentingClearLogConfirm: Bool = false
@State var isExporting = false
@State var exportString = ""
@ -166,7 +167,7 @@ struct EnvironmentMetricsLog: View {
titleVisibility: .visible
) {
Button("Delete all environment metrics?", role: .destructive) {
if clearTelemetry(destNum: node.num, metricsType: 1, context: context) {
if updateCoreDataController.clearTelemetry(destNum: node.num, metricsType: 1) {
Logger.services.error("Clear Environment Metrics Log Failed")
}
}
@ -199,11 +200,6 @@ struct EnvironmentMetricsLog: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
.fileExporter(
isPresented: $isExporting,
document: CsvDocument(emptyCsv: exportString),

View file

@ -10,6 +10,9 @@ struct DeleteNodeButton: View {
var connectedNode: NodeInfoEntity
var node: NodeInfoEntity
@EnvironmentObject
var queryCoreDataController: QueryCoreDataController
@State
private var isPresentingAlert = false
@ -31,10 +34,7 @@ struct DeleteNodeButton: View {
titleVisibility: .visible
) {
Button("Delete Node", role: .destructive) {
guard let deleteNode = getNodeInfo(
id: node.num,
context: context
) else {
guard let deleteNode = queryCoreDataController.getNodeInfo(id: node.num) else {
Logger.data.error("Unable to find node info to delete node \(node.num)")
return
}

View file

@ -14,6 +14,8 @@ import SwiftUI
struct WaypointForm: View {
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.managedObjectContext) private var context
@Environment(\.dismiss) private var dismiss
@State var waypoint: WaypointEntity
let distanceFormatter = MKDistanceFormatter()
@ -184,13 +186,14 @@ struct WaypointForm: View {
Menu {
Button("For me", action: {
bleManager.context!.delete(waypoint)
context.delete(waypoint)
do {
try bleManager.context!.save()
try context.save()
} catch {
bleManager.context!.rollback()
context.rollback()
}
dismiss() })
dismiss()
})
Button("For everyone", action: {
var newWaypoint = Waypoint()
newWaypoint.id = UInt32(waypoint.id)
@ -213,11 +216,11 @@ struct WaypointForm: View {
newWaypoint.expire = UInt32(1)
if bleManager.sendWaypoint(waypoint: newWaypoint) {
bleManager.context!.delete(waypoint)
context.delete(waypoint)
do {
try bleManager.context!.save()
try context.save()
} catch {
bleManager.context!.rollback()
context.rollback()
}
dismiss()
} else {
@ -351,7 +354,7 @@ struct WaypointForm: View {
}
.onAppear {
if waypoint.id > 0 {
let waypoint = getWaypoint(id: Int64(waypoint.id), context: bleManager.context!)
let waypoint = queryCoreDataController.getWaypoint(id: Int64(waypoint.id))
name = waypoint.name ?? "Dropped Pin"
description = waypoint.longDescription ?? ""
icon = String(UnicodeScalar(Int(waypoint.icon)) ?? "📍")

View file

@ -18,6 +18,7 @@ struct NodeDetail: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@State private var showingShutdownConfirm: Bool = false
@State private var showingRebootConfirm: Bool = false
@State private var dateFormatRelative: Bool = true
@ -34,10 +35,7 @@ struct NodeDetail: View {
var body: some View {
NavigationStack {
List {
let connectedNode = getNodeInfo(
id: bleManager.connectedPeripheral?.num ?? -1,
context: context
)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1)
Section("Hardware") {
NodeInfoItem(node: node)
@ -369,11 +367,6 @@ struct NodeDetail: View {
}
}
.listStyle(.insetGrouped)
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
}
}
}

View file

@ -253,9 +253,6 @@ struct NodeList: View {
}
}
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
Task {
await searchNodeList()
}

View file

@ -238,12 +238,9 @@ struct NodeMap: View {
name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName :
"?")
})
.onAppear(perform: {
.onAppear {
UIApplication.shared.isIdleTimerDisabled = true
if self.bleManager.context == nil {
self.bleManager.context = context
}
})
}
.onDisappear(perform: {
UIApplication.shared.isIdleTimerDisabled = false
})

View file

@ -13,6 +13,7 @@ struct PaxCounterLog: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var updateCoreDataController: UpdateCoreDataController
@State private var isPresentingClearLogConfirm: Bool = false
@State var isExporting = false
@ -175,7 +176,7 @@ struct PaxCounterLog: View {
titleVisibility: .visible
) {
Button("paxcounter.delete", role: .destructive) {
if clearPax(destNum: node.num, context: context) {
if updateCoreDataController.clearPax(destNum: node.num) {
Logger.services.info("Cleared Pax Counter for \(node.num)")
} else {
Logger.services.error("Clear Pax Counter Log Failed")
@ -209,11 +210,6 @@ struct PaxCounterLog: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
.fileExporter(
isPresented: $isExporting,
document: CsvDocument(emptyCsv: exportString),

View file

@ -10,6 +10,7 @@ import OSLog
struct PositionLog: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var updateCoreDataController: UpdateCoreDataController
@Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass?
@Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?
var useGrid: Bool {
@ -130,7 +131,7 @@ struct PositionLog: View {
titleVisibility: .visible
) {
Button("Delete all positions?", role: .destructive) {
if clearPositions(destNum: node.num, context: context) {
if updateCoreDataController.clearPositions(destNum: node.num) {
Logger.services.info("Successfully Cleared Position Log")
} else {
Logger.services.error("Clear Position Log Failed")
@ -179,10 +180,5 @@ struct PositionLog: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
}
}

View file

@ -145,10 +145,5 @@ struct TraceRouteLog: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
}
}

View file

@ -8,6 +8,7 @@ import OSLog
struct AppSettings: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var persistenceController: PersistenceController
@ObservedObject var tileManager = OfflineTileManager.shared
@State var totalDownloadedTileSize = ""
@State private var isPresentingCoreDataResetConfirm = false
@ -57,7 +58,7 @@ struct AppSettings: View {
Logger.services.error("🗄 Error Deleting Meshtastic.sqlite file \(error, privacy: .public)")
}
}
clearCoreDataDatabase(context: context, includeRoutes: true)
persistenceController.clearCoreDataDatabase(context: context, includeRoutes: true)
context.refreshAllObjects()
UserDefaults.standard.reset()
}
@ -94,10 +95,5 @@ struct AppSettings: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
}
}

View file

@ -280,11 +280,6 @@ struct Channels: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
}
}

View file

@ -12,6 +12,7 @@ import SwiftUI
struct BluetoothConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@State var hasChanges = false
@ -80,7 +81,7 @@ struct BluetoothConfig: View {
SaveConfigButton(node: node, hasChanges: $hasChanges) {
if let myNodeNum = bleManager.connectedPeripheral?.num,
let connectedNode = getNodeInfo(id: myNodeNum, context: context) {
let connectedNode = queryCoreDataController.getNodeInfo(id: myNodeNum) {
var bc = Config.BluetoothConfig()
bc.enabled = enabled
bc.mode = BluetoothModes(rawValue: mode)?.protoEnumValue() ?? Config.BluetoothConfig.PairingMode.randomPin
@ -107,14 +108,11 @@ struct BluetoothConfig: View {
}
)
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setBluetoothValues()
// Need to request a BluetoothConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node, node.bluetoothConfig == nil {
Logger.mesh.info("empty bluetooth config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: connectedPeripheral.num)
if let connectedNode {
_ = bleManager.requestBluetoothConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}

View file

@ -13,6 +13,9 @@ struct DeviceConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var persistenceController: PersistenceController
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@ -166,7 +169,7 @@ struct DeviceConfig: View {
if bleManager.sendNodeDBReset(fromUser: node!.user!, toUser: node!.user!) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
bleManager.disconnectPeripheral()
clearCoreDataDatabase(context: context, includeRoutes: false)
persistenceController.clearCoreDataDatabase(context: context, includeRoutes: false)
}
} else {
@ -191,7 +194,8 @@ struct DeviceConfig: View {
if bleManager.sendFactoryReset(fromUser: node!.user!, toUser: node!.user!) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
bleManager.disconnectPeripheral()
clearCoreDataDatabase(context: context, includeRoutes: false)
// TODO: re-enable me
// clearCoreDataDatabase(context: context, includeRoutes: false)
}
} else {
Logger.mesh.error("Factory Reset Failed")
@ -202,7 +206,7 @@ struct DeviceConfig: View {
}
HStack {
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if connectedNode != nil {
var dc = Config.DeviceConfig()
dc.role = DeviceRoles(rawValue: deviceRole)!.protoEnumValue()
@ -238,14 +242,11 @@ struct DeviceConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setDeviceValues()
// Need to request a LoRaConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.deviceConfig == nil {
Logger.mesh.info("empty device config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1)
if node != nil && connectedNode != nil && connectedNode?.user != nil {
_ = bleManager.requestDeviceConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -13,6 +13,7 @@ struct DisplayConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@ -129,7 +130,7 @@ struct DisplayConfig: View {
.disabled(self.bleManager.connectedPeripheral == nil || node?.displayConfig == nil)
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if connectedNode != nil {
var dc = Config.DisplayConfig()
dc.gpsFormat = GpsFormats(rawValue: gpsFormat)!.protoEnumValue()
@ -159,15 +160,12 @@ struct DisplayConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setDisplayValues()
// Need to request a LoRaConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.displayConfig == nil {
Logger.mesh.info("empty display config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0)
if node != nil && connectedNode != nil {
_ = bleManager.requestDisplayConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -26,6 +26,7 @@ struct LoRaConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
@FocusState var focusedField: Field?
@ -191,7 +192,7 @@ struct LoRaConfig: View {
.disabled(self.bleManager.connectedPeripheral == nil || node?.loRaConfig == nil)
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0)
if connectedNode != nil {
var lc = Config.LoRaConfig()
lc.hopLimit = UInt32(hopLimit)
@ -226,14 +227,11 @@ struct LoRaConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setLoRaValues()
// Need to request a LoRaConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.loRaConfig == nil {
Logger.mesh.info("empty lora config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if node != nil && connectedNode != nil {
_ = bleManager.requestLoRaConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -12,6 +12,7 @@ struct AmbientLightingConfig: View {
@Environment(\.self) var environment
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@ -59,7 +60,7 @@ struct AmbientLightingConfig: View {
.disabled(self.bleManager.connectedPeripheral == nil || node?.ambientLightingConfig == nil)
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if connectedNode != nil {
var al = ModuleConfig.AmbientLightingConfig()
al.ledState = ledState
@ -85,13 +86,10 @@ struct AmbientLightingConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setAmbientLightingConfigValue()
// Need to request a Ambient Lighting Config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.ambientLightingConfig == nil {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if node != nil && connectedNode != nil {
_ = bleManager.requestAmbientLightingConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -11,6 +11,7 @@ import SwiftUI
struct CannedMessagesConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@State private var isPresentingSaveConfirm: Bool = false
@ -178,7 +179,7 @@ struct CannedMessagesConfig: View {
.disabled(self.bleManager.connectedPeripheral == nil || node?.cannedMessageConfig == nil)
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1)
if hasChanges {
if connectedNode != nil {
var cmc = ModuleConfig.CannedMessageConfig()
@ -229,14 +230,11 @@ struct CannedMessagesConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setCannedMessagesValues()
// Need to request a CannedMessagesModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.cannedMessageConfig == nil {
Logger.mesh.info("empty canned messages module config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if node != nil && connectedNode != nil {
_ = bleManager.requestCannedMessagesModuleConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -26,6 +26,7 @@ struct DetectionSensorConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@State private var isPresentingSaveConfirm: Bool = false
@ -159,7 +160,7 @@ struct DetectionSensorConfig: View {
.disabled(self.bleManager.connectedPeripheral == nil || node?.detectionSensorConfig == nil)
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1)
if connectedNode != nil {
var dsc = ModuleConfig.DetectionSensorConfig()
dsc.enabled = self.enabled
@ -185,14 +186,11 @@ struct DetectionSensorConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setDetectionSensorValues()
// Need to request a Detection Sensor Module Config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.detectionSensorConfig == nil {
Logger.mesh.info("empty detection sensor module config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if node != nil && connectedNode != nil {
_ = bleManager.requestDetectionSensorModuleConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -12,6 +12,7 @@ struct ExternalNotificationConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@ -162,7 +163,7 @@ struct ExternalNotificationConfig: View {
}
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1)
if connectedNode != nil {
var enc = ModuleConfig.ExternalNotificationConfig()
enc.enabled = enabled
@ -195,14 +196,11 @@ struct ExternalNotificationConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setExternalNotificationValues()
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.externalNotificationConfig == nil {
Logger.mesh.info("empty external notification module config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if node != nil && connectedNode != nil {
_ = bleManager.requestExternalNotificationModuleConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -13,8 +13,11 @@ struct MQTTConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@State private var isPresentingSaveConfirm: Bool = false
@State var hasChanges: Bool = false
@State var enabled = false
@ -246,7 +249,7 @@ struct MQTTConfig: View {
}
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1)
if connectedNode != nil {
var mqtt = ModuleConfig.MQTTConfig()
mqtt.enabled = self.enabled
@ -357,14 +360,11 @@ struct MQTTConfig: View {
}
}
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setMqttValues()
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.mqttConfig == nil {
Logger.mesh.info("empty mqtt module config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if node != nil && connectedNode != nil {
_ = bleManager.requestMqttModuleConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -11,6 +11,7 @@ import SwiftUI
struct PaxCounterConfig: View {
@Environment(\.managedObjectContext) private var context
@EnvironmentObject private var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
let node: NodeInfoEntity?
@ -58,14 +59,11 @@ struct PaxCounterConfig: View {
)
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setPaxValues()
// Need to request a PAX Counter module config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.paxCounterConfig == nil {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0)
if node != nil && connectedNode != nil {
_ = bleManager.requestPaxCounterModuleConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}
@ -83,7 +81,7 @@ struct PaxCounterConfig: View {
}
SaveConfigButton(node: node, hasChanges: $hasChanges) {
guard let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context),
guard let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num),
let fromUser = connectedNode.user,
let toUser = node?.user else {
return

View file

@ -12,6 +12,7 @@ struct RangeTestConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@ -56,7 +57,7 @@ struct RangeTestConfig: View {
.disabled(self.bleManager.connectedPeripheral == nil || node?.rangeTestConfig == nil)
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if connectedNode != nil {
var rtc = ModuleConfig.RangeTestConfig()
rtc.enabled = enabled
@ -77,14 +78,11 @@ struct RangeTestConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setRangeTestValues()
// Need to request a RangeTestModule Config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.rangeTestConfig == nil {
Logger.mesh.debug("empty range test module config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if node != nil && connectedNode != nil {
_ = bleManager.requestRangeTestModuleConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -10,6 +10,7 @@ import SwiftUI
struct RtttlConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@ -50,7 +51,7 @@ struct RtttlConfig: View {
.disabled(self.bleManager.connectedPeripheral == nil || node?.rtttlConfig == nil)
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if connectedNode != nil {
let adminMessageId = bleManager.saveRtttlConfig(ringtone: ringtone.trimmingCharacters(in: .whitespacesAndNewlines), fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
if adminMessageId > 0 {
@ -67,13 +68,10 @@ struct RtttlConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setRtttLConfigValue()
// Need to request a Rtttl Config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && (node?.rtttlConfig == nil || node?.rtttlConfig?.ringtone?.count ?? 0 == 0) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if node != nil && connectedNode != nil {
_ = bleManager.requestRtttlConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -12,6 +12,7 @@ struct SerialConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@ -104,7 +105,7 @@ struct SerialConfig: View {
.disabled(self.bleManager.connectedPeripheral == nil || node?.serialConfig == nil)
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if connectedNode != nil {
var sc = ModuleConfig.SerialConfig()
sc.enabled = enabled
@ -133,14 +134,11 @@ struct SerialConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setSerialValues()
// Need to request a SerialModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.serialConfig == nil {
Logger.mesh.debug("empty serial module config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if node != nil && connectedNode != nil {
_ = bleManager.requestSerialModuleConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -12,6 +12,7 @@ struct StoreForwardConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@State private var isPresentingSaveConfirm: Bool = false
@ -108,7 +109,7 @@ struct StoreForwardConfig: View {
}
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1)
if connectedNode != nil {
/// Let the user set isRouter for the connected node, for nodes on the mesh set isRouter based
/// on receipt of a primary heartbeat
@ -142,14 +143,10 @@ struct StoreForwardConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
// Need to request a Detection Sensor Module Config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.storeForwardConfig == nil {
Logger.mesh.debug("empty store and forward module config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if node != nil && connectedNode != nil {
_ = bleManager.requestStoreAndForwardModuleConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -12,6 +12,7 @@ struct TelemetryConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@ -104,7 +105,7 @@ struct TelemetryConfig: View {
.disabled(self.bleManager.connectedPeripheral == nil || node?.telemetryConfig == nil)
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1)
if connectedNode != nil {
var tc = ModuleConfig.TelemetryConfig()
tc.deviceUpdateInterval = UInt32(deviceUpdateInterval)
@ -130,14 +131,11 @@ struct TelemetryConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setTelemetryValues()
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.telemetryConfig == nil {
Logger.mesh.info("empty telemetry module config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if node != nil && connectedNode != nil {
_ = bleManager.requestTelemetryModuleConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -12,6 +12,7 @@ struct NetworkConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@ -89,7 +90,7 @@ struct NetworkConfig: View {
.disabled(self.bleManager.connectedPeripheral == nil || node?.networkConfig == nil)
SaveConfigButton(node: node, hasChanges: $hasChanges) {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if connectedNode != nil {
var network = Config.NetworkConfig()
network.wifiEnabled = self.wifiEnabled
@ -114,14 +115,11 @@ struct NetworkConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setNetworkValues()
// Need to request a NetworkConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.networkConfig == nil {
Logger.mesh.info("empty network config")
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num)
if node != nil && connectedNode != nil {
_ = bleManager.requestNetworkConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}

View file

@ -27,6 +27,7 @@ struct PositionConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@State var hasChanges = false
@ -290,7 +291,7 @@ struct PositionConfig: View {
if fixedPosition && !supportedVersion {
_ = bleManager.sendPosition(channel: 0, destNum: node?.num ?? 0, wantResponse: true)
}
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral!.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral!.num)
if connectedNode != nil {
var pc = Config.PositionConfig()
@ -377,15 +378,12 @@ struct PositionConfig: View {
}
)
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setPositionValues()
supportedVersion = bleManager.connectedVersion == "0.0.0" || self.minimumVersion.compare(bleManager.connectedVersion, options: .numeric) == .orderedAscending || minimumVersion.compare(bleManager.connectedVersion, options: .numeric) == .orderedSame
// Need to request a PositionConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, node?.positionConfig == nil {
Logger.mesh.info("empty position config")
let connectedNode = getNodeInfo(id: connectedPeripheral.num, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: connectedPeripheral.num)
if let node, let connectedNode {
_ = bleManager.requestPositionConfig(
fromUser: connectedNode.user!,

View file

@ -4,6 +4,7 @@ import MeshtasticProtobufs
struct PowerConfig: View {
@Environment(\.managedObjectContext) private var context
@EnvironmentObject private var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
let node: NodeInfoEntity?
@ -118,10 +119,6 @@ struct PowerConfig: View {
}
}
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
Api().loadDeviceHardwareData { (hw) in
for device in hw {
@ -136,7 +133,7 @@ struct PowerConfig: View {
// Need to request a Power config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.powerConfig == nil {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0)
if node != nil && connectedNode != nil {
_ = bleManager.requestPowerConfig(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode?.myInfo?.adminIndex ?? 0)
}
@ -180,7 +177,7 @@ struct PowerConfig: View {
}
SaveConfigButton(node: node, hasChanges: $hasChanges) {
guard let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral.num, context: context),
guard let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral.num),
let fromUser = connectedNode.user,
let toUser = node?.user else {
return

View file

@ -12,6 +12,7 @@ import OSLog
struct Firmware: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
var node: NodeInfoEntity?
@State var minimumVersion = "2.3.15"
@State var version = ""
@ -108,7 +109,7 @@ struct Firmware: View {
.foregroundStyle(.gray)
.font(.caption)
Button {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0)
if connectedNode != nil {
if bleManager.sendEnterDfuMode(fromUser: connectedNode!.user!, toUser: node!.user!) {
@ -158,7 +159,7 @@ struct Firmware: View {
HStack(alignment: .center) {
Spacer()
Button {
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0, context: context)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? 0)
if connectedNode != nil {
if !bleManager.sendRebootOta(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode!.myInfo!.adminIndex) {
Logger.mesh.error("Reboot Failed")

View file

@ -205,9 +205,9 @@ struct Settings: View {
if selectedNode > 0 {
let node = nodes.first(where: { $0.num == newValue })
let connectedNode = nodes.first(where: { $0.num == preferredNodeNum })
preferredNodeNum = Int(connectedNode?.num ?? 0)// Int(bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral?.num ?? 0 : 0)
preferredNodeNum = Int(connectedNode?.num ?? 0)
if connectedNode != nil && connectedNode?.user != nil && connectedNode?.myInfo != nil && node?.user != nil && node?.metadata == nil {
let adminMessageId = bleManager.requestDeviceMetadata(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode!.myInfo!.adminIndex, context: context)
let adminMessageId = bleManager.requestDeviceMetadata(fromUser: connectedNode!.user!, toUser: node!.user!, adminIndex: connectedNode!.myInfo!.adminIndex, context: context)
if adminMessageId > 0 {
Logger.mesh.info("Sent node metadata request from node details")
}

View file

@ -238,7 +238,6 @@ struct ShareChannels: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
bleManager.context = context
generateChannelSet()
}
.onChange(of: includeChannel0) { _ in generateChannelSet() }

View file

@ -12,6 +12,7 @@ struct UserConfig: View {
@Environment(\.managedObjectContext) var context
@EnvironmentObject var bleManager: BLEManager
@EnvironmentObject var queryCoreDataController: QueryCoreDataController
@Environment(\.dismiss) private var goBack
var node: NodeInfoEntity?
@ -149,8 +150,8 @@ struct UserConfig: View {
return
}
let connectedUser = getUser(id: bleManager.connectedPeripheral?.num ?? -1, context: context)
let connectedNode = getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1, context: context)
let connectedUser = queryCoreDataController.getUser(id: bleManager.connectedPeripheral?.num ?? -1)
let connectedNode = queryCoreDataController.getNodeInfo(id: bleManager.connectedPeripheral?.num ?? -1)
if node != nil && connectedNode != nil {
if !isLicensed {