From ea7bc0fe6973b02b8fcfb1a9b9e9e422bee9171c Mon Sep 17 00:00:00 2001 From: liamcharger Date: Wed, 6 Mar 2024 14:12:32 -0500 Subject: [PATCH] Add full markdown support, clean up code, and fix occasional freeze --- InfiniLink.xcodeproj/project.pbxproj | 17 +++++++ InfiniLink/BLE/BLEManager.swift | 50 +++++++------------ InfiniLink/BLE/BLEUpdateHandler.swift | 4 +- .../Chart/ChartViewComponents.swift | 12 +++-- InfiniLink/Core/Home/DFU/DFUWithBLE.swift | 7 +-- 5 files changed, 48 insertions(+), 42 deletions(-) diff --git a/InfiniLink.xcodeproj/project.pbxproj b/InfiniLink.xcodeproj/project.pbxproj index e0a6e5ef..3d0bdf5e 100644 --- a/InfiniLink.xcodeproj/project.pbxproj +++ b/InfiniLink.xcodeproj/project.pbxproj @@ -59,6 +59,7 @@ 26D7817026CA004B00BBF555 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26D7816F26CA004B00BBF555 /* SettingsView.swift */; }; 26D7817A26CAD19F00BBF555 /* ColorPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26D7817926CAD19F00BBF555 /* ColorPalette.swift */; }; E021DAB32B489F58005C5E51 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E021DAB22B489F58005C5E51 /* Extensions.swift */; }; + E038F8EC2B98CFB600DFDE22 /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = E038F8EB2B98CFB600DFDE22 /* MarkdownUI */; }; E0754FDA2B83BBF800B35787 /* LV_IMG_Convert.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5DBC9A32B828DF4003E0A28 /* LV_IMG_Convert.swift */; }; E079ED012B78903B0038C0F2 /* WatchSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E079ED002B78903B0038C0F2 /* WatchSettingsView.swift */; }; E097C1192B4F0B7E005293D8 /* BatteryChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = E097C1182B4F0B7E005293D8 /* BatteryChart.swift */; }; @@ -240,6 +241,7 @@ 263B20C526CEB46800676BF0 /* SwiftUICharts in Frameworks */, E53F51352B718E4A008D4CE6 /* Zip in Frameworks */, 26A6315E26C498B7005AE404 /* NordicDFU in Frameworks */, + E038F8EC2B98CFB600DFDE22 /* MarkdownUI in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -636,6 +638,7 @@ 263B20C426CEB46800676BF0 /* SwiftUICharts */, E59398F92B58DA1F00D5840A /* SwiftyJSON */, E53F51342B718E4A008D4CE6 /* Zip */, + E038F8EB2B98CFB600DFDE22 /* MarkdownUI */, ); productName = "Infini-iOS"; productReference = 264BFE3E26BC51CE0050A223 /* InfiniLink.app */; @@ -718,6 +721,7 @@ 263B20C326CEB46800676BF0 /* XCRemoteSwiftPackageReference "SwiftUICharts" */, E59398F82B58DA1F00D5840A /* XCRemoteSwiftPackageReference "SwiftyJSON" */, E53F51332B718E4A008D4CE6 /* XCRemoteSwiftPackageReference "Zip" */, + E038F8EA2B98CFB600DFDE22 /* XCRemoteSwiftPackageReference "swift-markdown-ui" */, ); productRefGroup = 264BFE3F26BC51CE0050A223 /* Products */; projectDirPath = ""; @@ -1224,6 +1228,14 @@ kind = branch; }; }; + E038F8EA2B98CFB600DFDE22 /* XCRemoteSwiftPackageReference "swift-markdown-ui" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/gonzalezreal/swift-markdown-ui.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.3.0; + }; + }; E53F51332B718E4A008D4CE6 /* XCRemoteSwiftPackageReference "Zip" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/marmelroy/Zip.git"; @@ -1253,6 +1265,11 @@ package = 26A6315C26C498B7005AE404 /* XCRemoteSwiftPackageReference "IOS-DFU-Library" */; productName = NordicDFU; }; + E038F8EB2B98CFB600DFDE22 /* MarkdownUI */ = { + isa = XCSwiftPackageProductDependency; + package = E038F8EA2B98CFB600DFDE22 /* XCRemoteSwiftPackageReference "swift-markdown-ui" */; + productName = MarkdownUI; + }; E53F51342B718E4A008D4CE6 /* Zip */ = { isa = XCSwiftPackageProductDependency; package = E53F51332B718E4A008D4CE6 /* XCRemoteSwiftPackageReference "Zip" */; diff --git a/InfiniLink/BLE/BLEManager.swift b/InfiniLink/BLE/BLEManager.swift index 1a17b0e0..4ddff487 100644 --- a/InfiniLink/BLE/BLEManager.swift +++ b/InfiniLink/BLE/BLEManager.swift @@ -14,7 +14,7 @@ import SwiftUI class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate { @AppStorage("autoconnectUUID") var autoconnectUUID: String = "" - static let shared = BLEManager() + static let shared = BLEManager() var myCentral: CBCentralManager! var blefsTransfer: CBCharacteristic! @@ -60,48 +60,48 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate { let lengthTrack = CBUUID(string: "00000007-78FC-48FE-8E23-433B3A1942D0") } -// let cbuuidList = cbuuidList() -// var musicChars = musicCharacteristics() -// -// let settings = UserDefaults.standard + // let cbuuidList = cbuuidList() + // var musicChars = musicCharacteristics() + // + // let settings = UserDefaults.standard // UI flag variables @Published var isSwitchedOn = false // for now this is used to display if bluetooth is on in the main app screen. maybe an alert in the future? @Published var isScanning = false // another UI flag. Probably not necessary for anything but debugging. I dunno maybe a little swirly animation or something could be triggered by this @Published var isConnectedToPinetime = false // another flag published to update UI stuff. Can probably be implemented better in the future -// @Published var heartBPM: Double = 0 // published var to communicate the HRM data to the UI. + // @Published var heartBPM: Double = 0 // published var to communicate the HRM data to the UI. @Published var batteryLevel: Double = 0 // Same as heartBPM but for battery data -// @Published var firmwareVersion: String = "Disconnected" + // @Published var firmwareVersion: String = "Disconnected" @Published var setTimeError = false @Published var blePermissions: Bool! -// @Published var stepCount: Int = 0 -// @Published var stepCounting: Int = 0 - + // @Published var stepCount: Int = 0 + // @Published var stepCounting: Int = 0 + // Selecting and connecting variables @Published var peripherals = [Peripheral]() @Published var newPeripherals: [CBPeripheral] = [] // used to print human-readable device names to UI in selection process -// @Published var deviceToConnect: Int! // When the user selects a device from the UI, that peripheral's ID goes in this var, which is passed to the peripheralDictionary + // @Published var deviceToConnect: Int! // When the user selects a device from the UI, that peripheral's ID goes in this var, which is passed to the peripheralDictionary @Published var peripheralDictionary: [Int: CBPeripheral] = [:] // this is the dictionary that relates human-readable peripheral names to the CBPeripheral class that CoreBluetooth actually interacts with @Published var infiniTime: CBPeripheral! // variable to save the CBPeripheral that you're connecting to -// @Published var autoconnectPeripheral: CBPeripheral! + // @Published var autoconnectPeripheral: CBPeripheral! @Published var setAutoconnectUUID: String = "" // placeholder for now while I figure out how to save the whole device in UserDefaults to save "favorite" devices @Published var bleLogger = DebugLogManager.shared // MARK: logging - + var firstConnect: Bool = true // makes iOS connected message only show up on first connect, not if device drops connection and reconnects var disconnected: Bool = false var heartChartReconnect: Bool = true // skip first HRM transmission on every fresh connection to prevent saving of BS data -// var batChartReconnect: Bool = true // skip first HRM transmission on every fresh connection to prevent saving of BS data + // var batChartReconnect: Bool = true // skip first HRM transmission on every fresh connection to prevent saving of BS data // declare some CBUUIDs for easier reference @Published var autoconnectToDevice: Bool = false - + override init() { super.init() - + myCentral = CBCentralManager(delegate: self, queue: nil) myCentral.delegate = self if myCentral.state == .unauthorized { @@ -153,28 +153,15 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate { setAutoconnectUUID = peripheral.identifier.uuidString isConnectedToPinetime = true autoconnectToDevice = (autoconnectUUID == setAutoconnectUUID) - //autoconnectUUID == bleManager.setAutoconnectUUID } else { DebugLogManager.shared.debug(error: "Could not connect to device not named 'InfiniTime'. Device name: \(peripheral.name!)", log: .ble, date: Date()) } } - - func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { - -// var peripheralName: String! if let _ = advertisementData[CBAdvertisementDataLocalNameKey] as? String { -// peripheralName = name -// let devUUIDString: String = peripheral.identifier.uuidString -// let devUUID: CBUUID = CBUUID(string: devUUIDString) -// let newPeripheral = Peripheral(id: peripheralDictionary.count, name: peripheralName, rssi: RSSI.intValue, peripheralHash: peripheral.hash, deviceUUID: devUUID, stringUUID: peripheral.identifier.uuidString) if isConnectedToPinetime == false { guard BLEAutoconnectManager.shared.connect(peripheral: peripheral) else { -// if !peripherals.contains(where: {$0.deviceUUID == newPeripheral.deviceUUID}) { -// peripherals.append(newPeripheral) -// peripheralDictionary[newPeripheral.peripheralHash] = peripheral -// } if !newPeripherals.contains(where: {$0.identifier.uuidString == peripheral.identifier.uuidString}) { newPeripherals.append(peripheral) } @@ -206,12 +193,11 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate { func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { if error != nil { heartChartReconnect = true - //connect(peripheral: peripheral) central.connect(peripheral) - bleLogger.debug(error: "Peripheral disconnected. Reason: \(error!)", log: .ble, date: Date()) // MARK: logging + bleLogger.debug(error: "Peripheral disconnected. Reason: \(error!)", log: .ble, date: Date()) } else { DeviceInfoManager.init().clearDeviceInfo() - bleLogger.debug(error: "User initiated disconnect", log: .ble, date: Date()) // MARK: logging + bleLogger.debug(error: "User initiated disconnect", log: .ble, date: Date()) } UptimeManager.shared.lastDisconnect = Date() UptimeManager.shared.connectTime = nil diff --git a/InfiniLink/BLE/BLEUpdateHandler.swift b/InfiniLink/BLE/BLEUpdateHandler.swift index aab886fb..524458f1 100644 --- a/InfiniLink/BLE/BLEUpdateHandler.swift +++ b/InfiniLink/BLE/BLEUpdateHandler.swift @@ -36,8 +36,6 @@ struct BLEUpdatedCharacteristicHandler { } func handleUpdates(characteristic: CBCharacteristic, peripheral: CBPeripheral) { - weatherController.updateWeatherData(ignoreTimeLimits: false) - switch characteristic.uuid { case bleManagerVal.cbuuidList.musicControl: let musicControl = [UInt8](characteristic.value!) @@ -87,5 +85,7 @@ struct BLEUpdatedCharacteristicHandler { default: break } + + weatherController.updateWeatherData(ignoreTimeLimits: false) } } diff --git a/InfiniLink/Components/Chart/ChartViewComponents.swift b/InfiniLink/Components/Chart/ChartViewComponents.swift index bd5404e3..bc464238 100644 --- a/InfiniLink/Components/Chart/ChartViewComponents.swift +++ b/InfiniLink/Components/Chart/ChartViewComponents.swift @@ -30,15 +30,18 @@ struct BarView: View { } struct HorizontalLines: View { + @Environment(\.colorScheme) var colorScheme + var numbLines: Int var sizes: CGSize var height: CGFloat var body: some View { VStack(alignment: .center) { - ForEach((1...numbLines).reversed(), id: \.self) {numb in + ForEach((1...numbLines).reversed(), id: \.self) { numb in Rectangle() - .frame(width: sizes.width, height: 1).foregroundColor(Color(light: .lightGray, dark: .darkGray)) + .frame(width: sizes.width, height: 1) + .foregroundColor(colorScheme == .dark ? Color.darkGray : Color.lightGray) if numb != 1 { Spacer(minLength: (height - CGFloat(numbLines)) / CGFloat(numbLines - 1)) } @@ -49,6 +52,8 @@ struct HorizontalLines: View { } struct verticalLines: View { + @Environment(\.colorScheme) var colorScheme + var numbLines: Int var sizes: CGSize var height: CGFloat @@ -61,7 +66,8 @@ struct verticalLines: View { VStack() { ForEach((1...20).reversed(), id: \.self) {_ in Rectangle() - .frame(width: 1, height: height / ((20 * 2) - 1)).foregroundColor(Color(light: .lightGray, dark: .darkGray)) + .frame(width: 1, height: height / ((20 * 2) - 1)) + .foregroundColor(colorScheme == .dark ? Color.darkGray : Color.lightGray) if numb != 15 {Spacer(minLength: height / ((20 * 2) - 1))} } } diff --git a/InfiniLink/Core/Home/DFU/DFUWithBLE.swift b/InfiniLink/Core/Home/DFU/DFUWithBLE.swift index 6d1b58de..205581aa 100644 --- a/InfiniLink/Core/Home/DFU/DFUWithBLE.swift +++ b/InfiniLink/Core/Home/DFU/DFUWithBLE.swift @@ -9,6 +9,7 @@ import Foundation import SwiftUI +import MarkdownUI extension UIScreen { static let screenWidth = UIScreen.main.bounds.size.width @@ -215,11 +216,7 @@ struct NewUpdate: View { Divider() ScrollView { VStack { - if #available(iOS 15.0, *) { - Text(try! AttributedString(markdown: DownloadManager.shared.updateBody, options: AttributedString.MarkdownParsingOptions(interpretedSyntax: .inlineOnlyPreservingWhitespace))) - } else { - Text(DownloadManager.shared.updateBody) - } + Markdown(DownloadManager.shared.updateBody) } .padding() }