diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index b9129eb7..eaeaeda9 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -26,7 +26,8 @@ DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */; }; DD539502276DAA6A00AD86B1 /* MapLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD539501276DAA6A00AD86B1 /* MapLocation.swift */; }; DD6B85A62800915B000ACD6B /* CarBode in Frameworks */ = {isa = PBXBuildFile; productRef = DD6B85A52800915B000ACD6B /* CarBode */; }; - DD6B85A828009258000ACD6B /* Channel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6B85A728009258000ACD6B /* Channel.swift */; }; + DD6B85A828009258000ACD6B /* ShareChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6B85A728009258000ACD6B /* ShareChannel.swift */; }; + DD6B85AA2800DFE5000ACD6B /* QRCamera.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD6B85A92800DFE5000ACD6B /* QRCamera.swift */; }; DD8169F9271F1A6100F4AB02 /* MeshLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8169F8271F1A6100F4AB02 /* MeshLogger.swift */; }; DD8169FB271F1F3A00F4AB02 /* MeshLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */; }; DD8169FF272476C700F4AB02 /* LogDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD8169FE272476C700F4AB02 /* LogDocument.swift */; }; @@ -93,7 +94,8 @@ DD4DED8F27AD2975004BA27E /* cannedmessages.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = cannedmessages.pb.swift; sourceTree = ""; }; DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionEntityExtension.swift; sourceTree = ""; }; DD539501276DAA6A00AD86B1 /* MapLocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLocation.swift; sourceTree = ""; }; - DD6B85A728009258000ACD6B /* Channel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Channel.swift; sourceTree = ""; }; + DD6B85A728009258000ACD6B /* ShareChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareChannel.swift; sourceTree = ""; }; + DD6B85A92800DFE5000ACD6B /* QRCamera.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCamera.swift; sourceTree = ""; }; DD8169F8271F1A6100F4AB02 /* MeshLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLogger.swift; sourceTree = ""; }; DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLog.swift; sourceTree = ""; }; DD8169FE272476C700F4AB02 /* LogDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogDocument.swift; sourceTree = ""; }; @@ -204,7 +206,7 @@ DD4A911D2708C65400501B7E /* AppSettings.swift */, DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */, DD8169FE272476C700F4AB02 /* LogDocument.swift */, - DD6B85A728009258000ACD6B /* Channel.swift */, + DD6B85A728009258000ACD6B /* ShareChannel.swift */, ); path = Settings; sourceTree = ""; @@ -348,6 +350,7 @@ DD47E3D826F3093800029299 /* MessageBubble.swift */, DD90860B26F684AF00DC5189 /* BatteryIcon.swift */, DDF924C926FBB953009FE055 /* ConnectedDevice.swift */, + DD6B85A92800DFE5000ACD6B /* QRCamera.swift */, ); path = Helpers; sourceTree = ""; @@ -536,12 +539,13 @@ files = ( DD4DED9027AD2975004BA27E /* cannedmessages.pb.swift in Sources */, DD836AE726F6B38600ABCC23 /* Connect.swift in Sources */, + DD6B85AA2800DFE5000ACD6B /* QRCamera.swift in Sources */, DDAF8C6E26ED19040058C060 /* Extensions.swift in Sources */, DDC2E1A726CEB3400042C5E4 /* LocationHelper.swift in Sources */, DDAF8C5F26ED09B50058C060 /* radioconfig.pb.swift in Sources */, DD5394FE276BA0EF00AD86B1 /* PositionEntityExtension.swift in Sources */, DD913639270DFF4C00D7ACF3 /* LocalNotificationManager.swift in Sources */, - DD6B85A828009258000ACD6B /* Channel.swift in Sources */, + DD6B85A828009258000ACD6B /* ShareChannel.swift in Sources */, DDAF8C5326EB1DF10058C060 /* BLEManager.swift in Sources */, DDC4D568275499A500A4208E /* Persistence.swift in Sources */, DD90860E26F69BAE00DC5189 /* NodeMap.swift in Sources */, @@ -745,6 +749,7 @@ ENABLE_PREVIEWS = YES; INFOPLIST_FILE = MeshtasticClient/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; + "IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 15.2; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -776,6 +781,7 @@ ENABLE_PREVIEWS = YES; INFOPLIST_FILE = MeshtasticClient/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.0; + "IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 15.2; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index f5aa4704..7d21920f 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -384,6 +384,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph switch characteristic.uuid { case FROMRADIO_UUID: + if characteristic.value == nil || characteristic.value!.isEmpty { return } @@ -405,6 +406,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph let myInfo = MyInfoEntity(context: context!) myInfo.myNodeNum = Int64(decodedInfo.myInfo.myNodeNum) myInfo.hasGps = decodedInfo.myInfo.hasGps_p + myInfo.bitrate = decodedInfo.myInfo.bitrate // Swift does strings weird, this does work to get the version without the github hash let lastDotIndex = decodedInfo.myInfo.firmwareVersion.lastIndex(of: ".") @@ -437,6 +439,18 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph print("💾 Saved the All - Broadcast User") } + var settingsCalled = self.getSettings() + + if settingsCalled { + + print("💾 Called Get Settings") + + } else { + + print("💥 Get Settings Call Failed") + } + + } catch { print("💥 Error Saving the All - Broadcast User") @@ -1146,6 +1160,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph return success } + // Send Position public func sendPosition(destNum: Int64, wantResponse: Bool) -> Bool { var success = false @@ -1223,4 +1238,40 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } } } + + // MARK: Device Settings + public func getSettings() -> Bool { + + var adminPacket = AdminMessage() + adminPacket.getRadioRequest = true + + var meshPacket: MeshPacket = MeshPacket() + meshPacket.to = UInt32(connectedPeripheral.num) + meshPacket.from = UInt32(connectedPeripheral.num) + meshPacket.id = UInt32.random(in: UInt32(UInt8.max).. Path { + Path { path in + let width = rect.width + let height = rect.height + + path.addLines( [ + + CGPoint(x: 0, y: height * 0.25), + CGPoint(x: 0, y: 0), + CGPoint(x:width * 0.25, y:0) + ]) + + path.addLines( [ + + CGPoint(x: width * 0.75, y: 0), + CGPoint(x: width, y: 0), + CGPoint(x:width, y:height * 0.25) + ]) + + path.addLines( [ + + CGPoint(x: width, y: height * 0.75), + CGPoint(x: width, y: height), + CGPoint(x:width * 0.75, y: height) + ]) + + path.addLines( [ + + CGPoint(x:width * 0.25, y: height), + CGPoint(x:0, y: height), + CGPoint(x:0, y:height * 0.75) + + ]) + + } + } +} + +struct QRCamera: View { + @State var barcodeValue = "" + @State var torchIsOn = false + @State var showingAlert = false + @State var cameraPosition = AVCaptureDevice.Position.back + + var body: some View { + VStack { + Text("QRCode Scanner") + + Spacer() + + if cameraPosition == .back{ + Text("Using back camera") + }else{ + Text("Using front camera") + } + + Button(action: { + if cameraPosition == .back { + cameraPosition = .front + }else{ + cameraPosition = .back + } + }) { + if cameraPosition == .back{ + Text("Switch Camera to Front") + }else{ + Text("Switch Camera to Back") + } + } + + + Button(action: { + self.torchIsOn.toggle() + }) { + Text("Toggle Torch Light") + } + + Spacer() + + CBScanner( + supportBarcode: .constant([.qr, .code128]), + torchLightIsOn: $torchIsOn, + cameraPosition: $cameraPosition, + mockBarCode: .constant(BarcodeData(value:"My Test Data", type: .qr)) + ){ + print("BarCodeType =",$0.type.rawValue, "Value =",$0.value) + barcodeValue = $0.value + } + onDraw: { + print("Preview View Size = \($0.cameraPreviewView.bounds)") + print("Barcode Corners = \($0.corners)") + + let lineColor = UIColor.green + let fillColor = UIColor(red: 0, green: 1, blue: 0.2, alpha: 0.4) + //Draw Barcode corner + $0.draw(lineWidth: 1, lineColor: lineColor, fillColor: fillColor) + + }.frame(minWidth: 0, maxWidth: .infinity, minHeight: 400, maxHeight: 400, alignment: .topLeading) + .overlay(cameraFrame() + .stroke(lineWidth: 5) + .frame(width: 500, height: 250) + .foregroundColor(.blue)) + + Spacer() + + Text(barcodeValue) + + Spacer() + + }.alert(isPresented: $showingAlert) { + Alert(title: Text("Found Barcode"), message: Text("\(barcodeValue)"), dismissButton: .default(Text("Close"))) + } + } +} + +struct ModalScannerView_Previews: PreviewProvider { + static var previews: some View { + QRCamera() + } +} + diff --git a/MeshtasticClient/Views/Settings/AppSettings.swift b/MeshtasticClient/Views/Settings/AppSettings.swift index caf7f255..bc9e9668 100644 --- a/MeshtasticClient/Views/Settings/AppSettings.swift +++ b/MeshtasticClient/Views/Settings/AppSettings.swift @@ -206,6 +206,13 @@ struct AppSettings: View { .listRowSeparator(.visible) } } + Section(header: Text("MESH OPTIONS")) { + + NavigationLink(destination: ShareChannel()) { + Text("Share Your Channel vis QR Code") + } + + } Section(header: Text("MESSAGING OPTIONS")) { Picker("Keyboard Type", selection: $userSettings.keyboardType) { diff --git a/MeshtasticClient/Views/Settings/Channel.swift b/MeshtasticClient/Views/Settings/Channel.swift deleted file mode 100644 index 1c874aed..00000000 --- a/MeshtasticClient/Views/Settings/Channel.swift +++ /dev/null @@ -1,8 +0,0 @@ -// -// Channel.swift -// MeshtasticClient -// -// Created by Garth Vander Houwen on 4/8/22. -// - -import Foundation diff --git a/MeshtasticClient/Views/Settings/ShareChannel.swift b/MeshtasticClient/Views/Settings/ShareChannel.swift new file mode 100644 index 00000000..e734b454 --- /dev/null +++ b/MeshtasticClient/Views/Settings/ShareChannel.swift @@ -0,0 +1,75 @@ +// +// Channel.swift +// MeshtasticClient +// +// Created by Garth Vander Houwen on 4/8/22. +// +import SwiftUI +import CoreData +import CarBode + + +struct ShareChannel: View { + + @Environment(\.managedObjectContext) var context + @EnvironmentObject var bleManager: BLEManager + @EnvironmentObject var userSettings: UserSettings + + + @State var dataString = "Hello Carbode" + @State var barcodeType = CBBarcodeView.BarcodeType.qrCode + @State var rotate = CBBarcodeView.Orientation.up + + @State var barcodeImage: UIImage? + + + var body: some View { + + HStack { + + GeometryReader { bounds in + + ScrollView { + + VStack { + + let smallest = min(bounds.size.width, bounds.size.height) + + Text("Channel Name").font(.largeTitle) + CBBarcodeView(data: $dataString, + barcodeType: $barcodeType, + orientation: $rotate) + { image in + self.barcodeImage = image + }.frame( + minWidth: smallest * 0.9, + maxWidth: smallest * 0.9, + minHeight: smallest * 0.9, + maxHeight: smallest * 0.9, + alignment: .topLeading + ) + .padding(.bottom) + Text("Channel Details").font(.title) + + Text("Some helpful text about how this whole thing works goes here, also could add a share sheet icon and pass the link around.") + Spacer() + Text("Some helpful text about how this whole thing works goes here, also could add a share sheet icon and pass the link around.") + } + } + }.padding() + } + .navigationTitle("Share Channel") + .navigationBarTitleDisplayMode(.inline) + .navigationBarItems(trailing: + + ZStack { + + ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???") + }) + .onAppear { + + self.bleManager.context = context + } + .navigationViewStyle(StackNavigationViewStyle()) + } +}