mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Kill the CarBode!
This commit is contained in:
parent
ada29b167d
commit
be8577a610
9 changed files with 158 additions and 232 deletions
|
|
@ -25,9 +25,7 @@
|
|||
DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */ = {isa = PBXBuildFile; productRef = DD5394FB276993AD00AD86B1 /* SwiftProtobuf */; };
|
||||
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 /* 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 */; };
|
||||
|
|
@ -95,7 +93,6 @@
|
|||
DD5394FD276BA0EF00AD86B1 /* PositionEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PositionEntityExtension.swift; sourceTree = "<group>"; };
|
||||
DD539501276DAA6A00AD86B1 /* MapLocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLocation.swift; sourceTree = "<group>"; };
|
||||
DD6B85A728009258000ACD6B /* ShareChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareChannel.swift; sourceTree = "<group>"; };
|
||||
DD6B85A92800DFE5000ACD6B /* QRCamera.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCamera.swift; sourceTree = "<group>"; };
|
||||
DD8169F8271F1A6100F4AB02 /* MeshLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLogger.swift; sourceTree = "<group>"; };
|
||||
DD8169FA271F1F3A00F4AB02 /* MeshLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshLog.swift; sourceTree = "<group>"; };
|
||||
DD8169FE272476C700F4AB02 /* LogDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogDocument.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -140,7 +137,6 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DD6B85A62800915B000ACD6B /* CarBode in Frameworks */,
|
||||
C9697FA527933B8C00250207 /* SQLite in Frameworks */,
|
||||
DD5394FC276993AD00AD86B1 /* SwiftProtobuf in Frameworks */,
|
||||
);
|
||||
|
|
@ -350,7 +346,6 @@
|
|||
DD47E3D826F3093800029299 /* MessageBubble.swift */,
|
||||
DD90860B26F684AF00DC5189 /* BatteryIcon.swift */,
|
||||
DDF924C926FBB953009FE055 /* ConnectedDevice.swift */,
|
||||
DD6B85A92800DFE5000ACD6B /* QRCamera.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -396,7 +391,6 @@
|
|||
packageProductDependencies = (
|
||||
DD5394FB276993AD00AD86B1 /* SwiftProtobuf */,
|
||||
C9697FA427933B8C00250207 /* SQLite */,
|
||||
DD6B85A52800915B000ACD6B /* CarBode */,
|
||||
);
|
||||
productName = MeshtasticClient;
|
||||
productReference = DDC2E15426CE248E0042C5E4 /* MeshtasticClient.app */;
|
||||
|
|
@ -473,7 +467,6 @@
|
|||
packageReferences = (
|
||||
DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */,
|
||||
C9697FA327933B8C00250207 /* XCRemoteSwiftPackageReference "SQLite.swift" */,
|
||||
DD6B85A42800915B000ACD6B /* XCRemoteSwiftPackageReference "CarBode-Barcode-Scanner-For-SwiftUI" */,
|
||||
);
|
||||
productRefGroup = DDC2E15526CE248E0042C5E4 /* Products */;
|
||||
projectDirPath = "";
|
||||
|
|
@ -539,7 +532,6 @@
|
|||
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 */,
|
||||
|
|
@ -743,7 +735,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements;
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 20;
|
||||
CURRENT_PROJECT_VERSION = 2;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = GCH7VS5Y9R;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
|
|
@ -754,7 +746,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.2.53;
|
||||
MARKETING_VERSION = 1.3.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
@ -775,7 +767,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements;
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 20;
|
||||
CURRENT_PROJECT_VERSION = 2;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = GCH7VS5Y9R;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
|
|
@ -786,7 +778,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.2.53;
|
||||
MARKETING_VERSION = 1.3.1;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
|
|
@ -940,14 +932,6 @@
|
|||
minimumVersion = 1.0.0;
|
||||
};
|
||||
};
|
||||
DD6B85A42800915B000ACD6B /* XCRemoteSwiftPackageReference "CarBode-Barcode-Scanner-For-SwiftUI" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/heart/CarBode-Barcode-Scanner-For-SwiftUI";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 2.0.0;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
|
|
@ -961,11 +945,6 @@
|
|||
package = DD5394FA276993AD00AD86B1 /* XCRemoteSwiftPackageReference "swift-protobuf" */;
|
||||
productName = SwiftProtobuf;
|
||||
};
|
||||
DD6B85A52800915B000ACD6B /* CarBode */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DD6B85A42800915B000ACD6B /* XCRemoteSwiftPackageReference "CarBode-Barcode-Scanner-For-SwiftUI" */;
|
||||
productName = CarBode;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
|
||||
/* Begin XCVersionGroup section */
|
||||
|
|
|
|||
|
|
@ -1,22 +1,13 @@
|
|||
{
|
||||
"object": {
|
||||
"pins": [
|
||||
{
|
||||
"package": "CarBode",
|
||||
"repositoryURL": "https://github.com/heart/CarBode-Barcode-Scanner-For-SwiftUI",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "6167624ec47174900434f1c03dfa0b2dd5d19c0d",
|
||||
"version": "2.2.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "SQLite.swift",
|
||||
"repositoryURL": "https://github.com/stephencelis/SQLite.swift.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "60a65015f6402b7c34b9a924f755ca0a73afeeaa",
|
||||
"version": "0.13.1"
|
||||
"revision": "4d543d811ee644fa4cc4bfa0be996b4dd6ba0f54",
|
||||
"version": "0.13.3"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -24,8 +15,8 @@
|
|||
"repositoryURL": "https://github.com/apple/swift-protobuf.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "7e2c5f3cbbeea68e004915e3a8961e20bd11d824",
|
||||
"version": "1.18.0"
|
||||
"revision": "e1499bc69b9040b29184f7f2996f7bab467c1639",
|
||||
"version": "1.19.0"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -523,11 +523,13 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
|
||||
if decodedInfo.nodeInfo.hasDeviceMetrics {
|
||||
|
||||
newNode.batteryLevel = Int32(decodedInfo.nodeInfo.deviceMetrics.batteryLevel)
|
||||
newNode.voltage = decodedInfo.nodeInfo.deviceMetrics.voltage
|
||||
newNode.channelUtilization = decodedInfo.nodeInfo.deviceMetrics.channelUtilization
|
||||
self.connectedPeripheral.channelUtilization = newNode.channelUtilization
|
||||
newNode.airUtilTx = decodedInfo.nodeInfo.deviceMetrics.airUtilTx
|
||||
let newTelemetry = TelemetryEntity(context: context!)
|
||||
|
||||
newTelemetry.batteryLevel = Int32(decodedInfo.nodeInfo.deviceMetrics.batteryLevel)
|
||||
newTelemetry.voltage = decodedInfo.nodeInfo.deviceMetrics.voltage
|
||||
newTelemetry.channelUtilization = decodedInfo.nodeInfo.deviceMetrics.channelUtilization
|
||||
self.connectedPeripheral.channelUtilization = newTelemetry.channelUtilization
|
||||
newTelemetry.airUtilTx = decodedInfo.nodeInfo.deviceMetrics.airUtilTx
|
||||
self.connectedPeripheral.airTime = decodedInfo.nodeInfo.deviceMetrics.airUtilTx
|
||||
}
|
||||
|
||||
|
|
@ -988,7 +990,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
if let telemetryMessage = try? Telemetry(serializedData: decodedInfo.packet.decoded.payload) {
|
||||
|
||||
let telemetry = TelemetryEntity(context: context!)
|
||||
telemetry.num = Int64(decodedInfo.packet.from)
|
||||
print(decodedInfo.packet.decoded.requestID)
|
||||
print(telemetryMessage)
|
||||
}
|
||||
|
|
@ -1178,6 +1179,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
do {
|
||||
|
||||
let fetchedNode = try context?.fetch(fetchNode) as! [NodeInfoEntity]
|
||||
|
||||
|
||||
if fetchedNode.count == 1 {
|
||||
|
||||
|
|
@ -1207,10 +1209,9 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
print("📍 Sent a Position Packet from the phone to the device for node: \(fromNodeNum)")
|
||||
|
||||
if connectedPeripheral!.peripheral.state == CBPeripheralState.connected {
|
||||
|
||||
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
|
||||
|
||||
success = true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@
|
|||
<string>We use bluetooth to connect to nearby Meshtastic Devices</string>
|
||||
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||
<string>Bluetooth is used to connect an iPhone to a user's meshtastic device to allow text messaging and location data for the mesh network.</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>We use the camera to share channels using a QR Code</string>
|
||||
<key>NSLocationUsageDescription</key>
|
||||
<string>We use your location to display it on the mesh map as well as to have GPS coordinatess to send to the connected device.</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
<entity name="MyInfoEntity" representedClassName="MyInfoEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="bitrate" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="bleName" optional="YES" attributeType="String"/>
|
||||
<attribute name="errorCount" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="firmwareVersion" attributeType="String"/>
|
||||
<attribute name="hasGps" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="hasWifi" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
|
|
@ -31,6 +32,7 @@
|
|||
<attribute name="messageTimeoutMsec" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="minAppVersion" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="myNodeNum" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="rebootCount" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<relationship name="myInfoNode" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="myInfo" inverseEntity="NodeInfoEntity"/>
|
||||
<uniquenessConstraints>
|
||||
<uniquenessConstraint>
|
||||
|
|
@ -39,15 +41,11 @@
|
|||
</uniquenessConstraints>
|
||||
</entity>
|
||||
<entity name="NodeInfoEntity" representedClassName="NodeInfoEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="airUtilTx" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="batteryLevel" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="bleName" optional="YES" attributeType="String"/>
|
||||
<attribute name="channelUtilization" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="id" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="lastHeard" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="num" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="snr" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="voltage" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<relationship name="myInfo" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="MyInfoEntity" inverseName="myInfoNode" inverseEntity="MyInfoEntity"/>
|
||||
<relationship name="positions" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="PositionEntity" inverseName="nodePosition" inverseEntity="PositionEntity"/>
|
||||
<relationship name="telemetries" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="TelemetryEntity" inverseName="nodeTelemetry" inverseEntity="TelemetryEntity"/>
|
||||
|
|
@ -67,10 +65,12 @@
|
|||
<relationship name="nodePosition" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="NodeInfoEntity" inverseName="positions" inverseEntity="NodeInfoEntity"/>
|
||||
</entity>
|
||||
<entity name="TelemetryEntity" representedClassName="TelemetryEntity" syncable="YES" codeGenerationType="class">
|
||||
<attribute name="airUtilTx" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="barometricPressure" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="batteryLevel" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="channelUtilization" optional="YES" attributeType="Float" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="current" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="gasResistance" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="num" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="relativeHumidity" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="temperature" optional="YES" attributeType="Float" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
<attribute name="time" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
|
|
@ -94,10 +94,10 @@
|
|||
</entity>
|
||||
<elements>
|
||||
<element name="MessageEntity" positionX="-36" positionY="63" width="128" height="215"/>
|
||||
<element name="MyInfoEntity" positionX="-18" positionY="81" width="128" height="179"/>
|
||||
<element name="NodeInfoEntity" positionX="-63" positionY="-18" width="128" height="14"/>
|
||||
<element name="MyInfoEntity" positionX="-18" positionY="81" width="128" height="209"/>
|
||||
<element name="NodeInfoEntity" positionX="-63" positionY="-18" width="128" height="164"/>
|
||||
<element name="PositionEntity" positionX="-54" positionY="54" width="128" height="119"/>
|
||||
<element name="TelemetryEntity" positionX="160" positionY="192" width="128" height="14"/>
|
||||
<element name="TelemetryEntity" positionX="160" positionY="192" width="128" height="194"/>
|
||||
<element name="UserEntity" positionX="0" positionY="144" width="128" height="200"/>
|
||||
</elements>
|
||||
</model>
|
||||
|
|
@ -1171,9 +1171,27 @@ struct DataMessage {
|
|||
/// Formerly named typ and of type Type
|
||||
var portnum: PortNum = .unknownApp
|
||||
|
||||
var payloadVariant: DataMessage.OneOf_PayloadVariant? = nil
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
var payload: Data = Data()
|
||||
var payload: Data {
|
||||
get {
|
||||
if case .payload(let v)? = payloadVariant {return v}
|
||||
return Data()
|
||||
}
|
||||
set {payloadVariant = .payload(newValue)}
|
||||
}
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
var payloadCompressed: Data {
|
||||
get {
|
||||
if case .payloadCompressed(let v)? = payloadVariant {return v}
|
||||
return Data()
|
||||
}
|
||||
set {payloadVariant = .payloadCompressed(newValue)}
|
||||
}
|
||||
|
||||
///
|
||||
/// Not normally used, but for testing a sender can request that recipient
|
||||
|
|
@ -1222,6 +1240,34 @@ struct DataMessage {
|
|||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
enum OneOf_PayloadVariant: Equatable {
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
case payload(Data)
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
case payloadCompressed(Data)
|
||||
|
||||
#if !swift(>=4.1)
|
||||
static func ==(lhs: DataMessage.OneOf_PayloadVariant, rhs: DataMessage.OneOf_PayloadVariant) -> Bool {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch (lhs, rhs) {
|
||||
case (.payload, .payload): return {
|
||||
guard case .payload(let l) = lhs, case .payload(let r) = rhs else { preconditionFailure() }
|
||||
return l == r
|
||||
}()
|
||||
case (.payloadCompressed, .payloadCompressed): return {
|
||||
guard case .payloadCompressed(let l) = lhs, case .payloadCompressed(let r) = rhs else { preconditionFailure() }
|
||||
return l == r
|
||||
}()
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _location: Location? = nil
|
||||
|
|
@ -2266,6 +2312,7 @@ extension Routing: @unchecked Sendable {}
|
|||
extension Routing.OneOf_Variant: @unchecked Sendable {}
|
||||
extension Routing.Error: @unchecked Sendable {}
|
||||
extension DataMessage: @unchecked Sendable {}
|
||||
extension DataMessage.OneOf_PayloadVariant: @unchecked Sendable {}
|
||||
extension Location: @unchecked Sendable {}
|
||||
extension MeshPacket: @unchecked Sendable {}
|
||||
extension MeshPacket.OneOf_PayloadVariant: @unchecked Sendable {}
|
||||
|
|
@ -2830,6 +2877,7 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "portnum"),
|
||||
2: .same(proto: "payload"),
|
||||
10: .standard(proto: "payload_compressed"),
|
||||
3: .standard(proto: "want_response"),
|
||||
4: .same(proto: "dest"),
|
||||
5: .same(proto: "source"),
|
||||
|
|
@ -2846,7 +2894,14 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularEnumField(value: &self.portnum) }()
|
||||
case 2: try { try decoder.decodeSingularBytesField(value: &self.payload) }()
|
||||
case 2: try {
|
||||
var v: Data?
|
||||
try decoder.decodeSingularBytesField(value: &v)
|
||||
if let v = v {
|
||||
if self.payloadVariant != nil {try decoder.handleConflictingOneOf()}
|
||||
self.payloadVariant = .payload(v)
|
||||
}
|
||||
}()
|
||||
case 3: try { try decoder.decodeSingularBoolField(value: &self.wantResponse) }()
|
||||
case 4: try { try decoder.decodeSingularFixed32Field(value: &self.dest) }()
|
||||
case 5: try { try decoder.decodeSingularFixed32Field(value: &self.source) }()
|
||||
|
|
@ -2854,6 +2909,14 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
case 7: try { try decoder.decodeSingularFixed32Field(value: &self.replyID) }()
|
||||
case 8: try { try decoder.decodeSingularFixed32Field(value: &self.emoji) }()
|
||||
case 9: try { try decoder.decodeSingularMessageField(value: &self._location) }()
|
||||
case 10: try {
|
||||
var v: Data?
|
||||
try decoder.decodeSingularBytesField(value: &v)
|
||||
if let v = v {
|
||||
if self.payloadVariant != nil {try decoder.handleConflictingOneOf()}
|
||||
self.payloadVariant = .payloadCompressed(v)
|
||||
}
|
||||
}()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
|
@ -2867,9 +2930,9 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
if self.portnum != .unknownApp {
|
||||
try visitor.visitSingularEnumField(value: self.portnum, fieldNumber: 1)
|
||||
}
|
||||
if !self.payload.isEmpty {
|
||||
try visitor.visitSingularBytesField(value: self.payload, fieldNumber: 2)
|
||||
}
|
||||
try { if case .payload(let v)? = self.payloadVariant {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
if self.wantResponse != false {
|
||||
try visitor.visitSingularBoolField(value: self.wantResponse, fieldNumber: 3)
|
||||
}
|
||||
|
|
@ -2891,12 +2954,15 @@ extension DataMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
try { if let v = self._location {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 9)
|
||||
} }()
|
||||
try { if case .payloadCompressed(let v)? = self.payloadVariant {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 10)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: DataMessage, rhs: DataMessage) -> Bool {
|
||||
if lhs.portnum != rhs.portnum {return false}
|
||||
if lhs.payload != rhs.payload {return false}
|
||||
if lhs.payloadVariant != rhs.payloadVariant {return false}
|
||||
if lhs.wantResponse != rhs.wantResponse {return false}
|
||||
if lhs.dest != rhs.dest {return false}
|
||||
if lhs.source != rhs.source {return false}
|
||||
|
|
|
|||
|
|
@ -1,133 +0,0 @@
|
|||
//
|
||||
// QRCamera.swift
|
||||
// MeshtasticClient
|
||||
//
|
||||
// Created by Garth Vander Houwen on 4/8/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import CarBode
|
||||
import AVFoundation
|
||||
|
||||
struct cameraFrame: Shape {
|
||||
func path(in rect: CGRect) -> 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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +104,8 @@ struct NodeDetail: View {
|
|||
}
|
||||
}
|
||||
.padding(5)
|
||||
|
||||
|
||||
|
||||
if node.snr > 0 {
|
||||
Divider()
|
||||
VStack(alignment: .center) {
|
||||
|
|
|
|||
|
|
@ -6,69 +6,88 @@
|
|||
//
|
||||
import SwiftUI
|
||||
import CoreData
|
||||
import CarBode
|
||||
import CoreImage.CIFilterBuiltins
|
||||
|
||||
|
||||
struct QrCodeImage {
|
||||
let context = CIContext()
|
||||
|
||||
func generateQRCode(from text: String) -> UIImage {
|
||||
var qrImage = UIImage(systemName: "xmark.circle") ?? UIImage()
|
||||
let data = Data(text.utf8)
|
||||
let filter = CIFilter.qrCodeGenerator()
|
||||
filter.setValue(data, forKey: "inputMessage")
|
||||
|
||||
let transform = CGAffineTransform(scaleX: 15, y: 15)
|
||||
if let outputImage = filter.outputImage?.transformed(by: transform) {
|
||||
if let image = context.createCGImage(
|
||||
outputImage,
|
||||
from: outputImage.extent) {
|
||||
qrImage = UIImage(cgImage: image)
|
||||
}
|
||||
}
|
||||
return qrImage
|
||||
}
|
||||
}
|
||||
|
||||
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?
|
||||
|
||||
|
||||
|
||||
@State private var text = "meshtastic.org"
|
||||
var qrCodeImage = QrCodeImage()
|
||||
|
||||
var body: some View {
|
||||
|
||||
HStack {
|
||||
|
||||
VStack {
|
||||
|
||||
GeometryReader { bounds in
|
||||
|
||||
let smallest = min(bounds.size.width, bounds.size.height)
|
||||
|
||||
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(
|
||||
VStack {
|
||||
Text("Scan the QR code below with the Apple or Android device you would like to share with your channel settings with.")
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.font(.callout)
|
||||
.padding()
|
||||
Spacer()
|
||||
|
||||
let image = qrCodeImage.generateQRCode(from: text)
|
||||
Image(uiImage: image)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(
|
||||
minWidth: smallest * 0.9,
|
||||
maxWidth: smallest * 0.9,
|
||||
minHeight: smallest * 0.9,
|
||||
maxHeight: smallest * 0.9,
|
||||
alignment: .topLeading
|
||||
alignment: .center
|
||||
)
|
||||
.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.")
|
||||
Text("Channel Name (Long/Slow)").font(.title)
|
||||
Spacer()
|
||||
}
|
||||
.frame(width: bounds.size.width, height: bounds.size.height)
|
||||
}
|
||||
}.padding()
|
||||
}
|
||||
.navigationTitle("Share Channel")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.navigationBarItems(trailing:
|
||||
}
|
||||
.navigationTitle("Share Channel")
|
||||
.navigationBarTitleDisplayMode(.automatic)
|
||||
.navigationBarItems(trailing:
|
||||
|
||||
ZStack {
|
||||
ZStack {
|
||||
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???")
|
||||
})
|
||||
.onAppear {
|
||||
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "???")
|
||||
})
|
||||
.onAppear {
|
||||
|
||||
self.bleManager.context = context
|
||||
self.bleManager.context = context
|
||||
}
|
||||
|
||||
}
|
||||
.navigationViewStyle(StackNavigationViewStyle())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue