From: liangzhenying <867174124@qq.com> Date: Fri, 12 Sep 2025 07:08:05 +0000 (+0800) Subject: 对话请求加了loading X-Git-Tag: 1.0.2~101 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=69e8f115afe5c7047bcee85205bf7654d40da279;p=mirrors%2FShenYin.git 对话请求加了loading --- diff --git a/ShenYin/Podfile.lock b/ShenYin/Podfile.lock index be12f21..3e86ec9 100644 --- a/ShenYin/Podfile.lock +++ b/ShenYin/Podfile.lock @@ -52,8 +52,6 @@ PODS: - Moya/Core (= 15.0.0) - Moya/Core (15.0.0): - Alamofire (~> 5.0) - - MultiSlider (2.2.0): - - SweeterSwift - netfox (1.21.0) - Realm (20.0.3): - Realm/Headers (= 20.0.3) @@ -65,7 +63,6 @@ PODS: - SVProgressHUD (2.3.1): - SVProgressHUD/Core (= 2.3.1) - SVProgressHUD/Core (2.3.1) - - SweeterSwift (1.2.6) - SwiftDate (7.0.0) - swiftScan (1.2.1) - TabPageViewController (0.2.8) @@ -89,7 +86,6 @@ DEPENDENCIES: - Kingfisher (~> 6.0) - MJRefresh - Moya - - MultiSlider - netfox - RealmSwift - SnapKit @@ -123,14 +119,12 @@ SPEC REPOS: - Kingfisher - MJRefresh - Moya - - MultiSlider - netfox - Realm - RealmSwift - SnapKit - SocketRocket - SVProgressHUD - - SweeterSwift - SwiftDate - swiftScan - TabPageViewController @@ -158,14 +152,12 @@ SPEC CHECKSUMS: Kingfisher: 016c8b653a35add51dd34a3aba36b580041acc74 MJRefresh: ff9e531227924c84ce459338414550a05d2aea78 Moya: 138f0573e53411fb3dc17016add0b748dfbd78ee - MultiSlider: 9667217199a051fa729bf54986d68fb9b911554c netfox: 9d5cc727fe7576c4c7688a2504618a156b7d44b7 Realm: 853e5089d6042dff807bda000277eadfe2da93d2 RealmSwift: f33c19577cefcbf681345d721fcbc7b42be4c949 SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22 - SweeterSwift: 1eca266517c703d7376e723a21926f5cb2ba4d0f SwiftDate: bbc26e26fc8c0c33fbee8c140c5e8a68293a148a swiftScan: 0849e7d7c1c641384767a573ee8cb90b88d1ddd9 TabPageViewController: 8bd4104909754416b35a98f3b72a5b674ab20dd5 @@ -174,6 +166,6 @@ SPEC CHECKSUMS: YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30 YYText: 5c461d709e24d55a182d1441c41dc639a18a4849 -PODFILE CHECKSUM: 826428f9bd4197f6e9759f68eaf9008f80c0563b +PODFILE CHECKSUM: bc7d3a8004029604d5620b967136223e19d8a67d COCOAPODS: 1.16.2 diff --git a/ShenYin/ShenYin.xcodeproj/project.pbxproj b/ShenYin/ShenYin.xcodeproj/project.pbxproj index de54e87..52afbf1 100644 --- a/ShenYin/ShenYin.xcodeproj/project.pbxproj +++ b/ShenYin/ShenYin.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* Begin PBXBuildFile section */ 3F79C6142E6055E500EC38B9 /* JoyGemAI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F79C4902E603B4700EC38B9 /* JoyGemAI.framework */; }; 3F79C6152E6055E500EC38B9 /* JoyGemAI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3F79C4902E603B4700EC38B9 /* JoyGemAI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 3FF8A4622E72CBBA00271F9E /* DSWaveformImage in Frameworks */ = {isa = PBXBuildFile; productRef = 3FF8A4612E72CBBA00271F9E /* DSWaveformImage */; }; + 3FF8A4642E72CBBA00271F9E /* DSWaveformImageViews in Frameworks */ = {isa = PBXBuildFile; productRef = 3FF8A4632E72CBBA00271F9E /* DSWaveformImageViews */; }; F2E449CAD5874BE652A69B50 /* Pods_ShenYin.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3862D5561144E20721225B96 /* Pods_ShenYin.framework */; }; /* End PBXBuildFile section */ @@ -63,7 +65,9 @@ buildActionMask = 2147483647; files = ( F2E449CAD5874BE652A69B50 /* Pods_ShenYin.framework in Frameworks */, + 3FF8A4622E72CBBA00271F9E /* DSWaveformImage in Frameworks */, 3F79C6142E6055E500EC38B9 /* JoyGemAI.framework in Frameworks */, + 3FF8A4642E72CBBA00271F9E /* DSWaveformImageViews in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -158,6 +162,9 @@ ); mainGroup = 3F887B932E38D8DC00C98658; minimizedProjectReferenceProxies = 1; + packageReferences = ( + 3FF8A4602E72CBBA00271F9E /* XCRemoteSwiftPackageReference "DSWaveformImage" */, + ); preferredProjectObjectVersion = 77; productRefGroup = 3F887B9D2E38D8DC00C98658 /* Products */; projectDirPath = ""; @@ -187,10 +194,14 @@ inputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-ShenYin/Pods-ShenYin-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); + inputPaths = ( + ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( "${PODS_ROOT}/Target Support Files/Pods-ShenYin/Pods-ShenYin-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ShenYin/Pods-ShenYin-frameworks.sh\"\n"; @@ -457,6 +468,30 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 3FF8A4602E72CBBA00271F9E /* XCRemoteSwiftPackageReference "DSWaveformImage" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/dmrschmidt/DSWaveformImage"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 14.2.2; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 3FF8A4612E72CBBA00271F9E /* DSWaveformImage */ = { + isa = XCSwiftPackageProductDependency; + package = 3FF8A4602E72CBBA00271F9E /* XCRemoteSwiftPackageReference "DSWaveformImage" */; + productName = DSWaveformImage; + }; + 3FF8A4632E72CBBA00271F9E /* DSWaveformImageViews */ = { + isa = XCSwiftPackageProductDependency; + package = 3FF8A4602E72CBBA00271F9E /* XCRemoteSwiftPackageReference "DSWaveformImage" */; + productName = DSWaveformImageViews; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 3F887B942E38D8DC00C98658 /* Project object */; } diff --git a/ShenYin/ShenYin.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ShenYin/ShenYin.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..6851bcf --- /dev/null +++ b/ShenYin/ShenYin.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,15 @@ +{ + "originHash" : "eb3e6467aa3b79663b371a20cbe7f1b7c7a6a3c9f98e6945bc9704361b5ae42d", + "pins" : [ + { + "identity" : "dswaveformimage", + "kind" : "remoteSourceControl", + "location" : "https://github.com/dmrschmidt/DSWaveformImage", + "state" : { + "revision" : "4c56578ee10128ee2b2c04c9c5aa73812de722db", + "version" : "14.2.2" + } + } + ], + "version" : 3 +} diff --git a/ShenYin/ShenYin/AppLaunch.swift b/ShenYin/ShenYin/AppLaunch.swift index 4004d61..eb00957 100644 --- a/ShenYin/ShenYin/AppLaunch.swift +++ b/ShenYin/ShenYin/AppLaunch.swift @@ -13,6 +13,7 @@ class AppLaunch:NSObject{ @MainActor static func start(){ JoySdkManager.shared.setupSdk() setupKeyboard() + loadCache() } @MainActor static func setupKeyboard(){ @@ -23,4 +24,13 @@ class AppLaunch:NSObject{ IQKeyboardManager.shared.isEnabled = true IQKeyboardManager.shared.resignOnTouchOutside = true } + static func loadCache(){ + let list = DeviceCache.shared.getDeviceList() + Logger.debug("缓存设备",list) + if list.count > 0 { + CacheManager.shared.currentDevice = list.first + BleManager.shared.startScanDevice() + App.shared.enter() + } + } } diff --git a/ShenYin/ShenYin/Assets.xcassets/AppIcon.appiconset/20250911-142330.png b/ShenYin/ShenYin/Assets.xcassets/AppIcon.appiconset/20250911-142330.png new file mode 100644 index 0000000..1484aa2 Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/AppIcon.appiconset/20250911-142330.png differ diff --git a/ShenYin/ShenYin/Assets.xcassets/AppIcon.appiconset/Contents.json b/ShenYin/ShenYin/Assets.xcassets/AppIcon.appiconset/Contents.json index 2305880..ba8a194 100644 --- a/ShenYin/ShenYin/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/ShenYin/ShenYin/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,28 +1,7 @@ { "images" : [ { - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "tinted" - } - ], + "filename" : "20250911-142330.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" diff --git a/ShenYin/ShenYin/Ble/BleManager.swift b/ShenYin/ShenYin/Ble/BleManager.swift index 17c8cc3..88d6639 100644 --- a/ShenYin/ShenYin/Ble/BleManager.swift +++ b/ShenYin/ShenYin/Ble/BleManager.swift @@ -8,7 +8,6 @@ import UIKit import CoreBluetooth import JoyGemAI -import SVProgressHUD import AVFAudio class BleManager: NSObject { var discoverDeviceCallback: (([CBPeripheral]) -> Void)? @@ -66,24 +65,25 @@ extension BleManager:CBCentralManagerDelegate{ } devices.append(peripheral) - print(peripheral) + Logger.debug(peripheral) discoverDeviceCallback?(devices) + checkConnect() } func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { stopScanDevice() - print("蓝牙已连接 \(peripheral)") + Logger.debug("蓝牙已连接 \(peripheral)") connectPeripheral = peripheral peripheral.delegate = self peripheral.discoverServices([CBUUID(string: kJoyGemAIServiceUUID)]); didConnectDeviceCallback?(connectPeripheral!) } func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { - print("peripheral: %@ failed to connect", peripheral) - SVProgressHUD.dismiss() + Logger.debug("peripheral: %@ failed to connect", peripheral) + YLprogressHUD.hidden() } func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { - print("蓝牙已断开 \(peripheral)") + Logger.debug("蓝牙已断开 \(peripheral)") disConnectDeviceCallback?(peripheral) } } @@ -93,9 +93,9 @@ extension BleManager: CBPeripheralDelegate { func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { - print("发现服务成功") + Logger.debug("发现服务成功") for service in peripheral.services! { - print("peripheral service: %@", service) + Logger.debug("peripheral service: %@", service) peripheral.discoverCharacteristics(nil, for: service) } @@ -119,7 +119,7 @@ extension BleManager: CBPeripheralDelegate { func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: (any Error)?) { if (characteristic.isNotifying == true && characteristic.service?.uuid.uuidString == kJoyGemAIServiceUUID && characteristic.uuid.uuidString == kJoyGemAICharacteristicNotifyUUID) { //MARK: 使能成功时需要 - print("特征使能成功") + Logger.debug("特征使能成功") JoyGemAIManager.shared().bleConnected() } } @@ -136,26 +136,38 @@ extension BleManager: CBPeripheralDelegate { func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: (any Error)?) { } - } extension BleManager{ - // MARK: - Public Methods func startScanDevice() { - print("扫描中...") + centralManager.stopScan() + Logger.debug("扫描中...") devices = [] centralManager.scanForPeripherals(withServices: [CBUUID(string: kJoyGemAIServiceUUID)],options: [CBCentralManagerScanOptionAllowDuplicatesKey : false]) + discoverDeviceCallback?(devices) + } + + func checkConnect(){ let list = centralManager.retrieveConnectedPeripherals(withServices: [CBUUID(string: kJoyGemAIServiceUUID)]) for item in list { devices.append(item) break } - if list.count > 0 { - print("缓存",list) + + for item in devices{ + if let current = CacheManager.shared.currentDevice,current.uuid == item.identifier.uuidString { + connectPeripheral(item) + return + } + } + + if connectPeripheral == nil || connectPeripheral?.state == .disconnected { + DispatchQueue.main.asyncAfter(deadline:.now() + 3) { + self.checkConnect() + } } - discoverDeviceCallback?(devices) } func stopScanDevice() { @@ -163,13 +175,9 @@ extension BleManager{ } func connectPeripheral(_ peripheral: CBPeripheral) { - print("连接中...") -// YLprogressHUD.showLoading() + Logger.debug("连接中...") centralManager.connect(peripheral, options: [CBConnectPeripheralOptionEnableTransportBridgingKey:true]) - SVProgressHUD.show(withStatus: "连接中") - // DispatchQueue.main.asyncAfter(deadline: .now() + 15){[weak self] in - // self?.cancel() - // } + YLprogressHUD.showLoading() } func cancel() { @@ -185,32 +193,32 @@ extension BleManager : JoyGemAIManagerDelegate { } func joyGemAuthSuccessCallback() { - YLprogressHUD.showAutoHiden(text: "鉴权成功"){ + ConnectPopView().showAutoHide { App.shared.enter() } - + CacheManager.shared.saveDevice(DeviceModel(name: connectPeripheral?.name ?? "", uuid: connectPeripheral?.identifier.uuidString ?? "")) PcmSound.sharedInstance().setup(16000, withchannels: 1) let options: AVAudioSession.CategoryOptions = [.allowBluetooth] do { try AVAudioSession.sharedInstance().setCategory(.playback, options: [options]) try AVAudioSession.sharedInstance().setActive(true) } catch { - print(error) + Logger.debug(error) } } func joyGemAction(_ action: JoyGemActionMode) { switch action { case .cancel: - SVProgressHUD.showInfo(withStatus: "请求关闭录音功能/通知关闭了对话") + YLprogressHUD.showAutoHiden("请求关闭录音功能/通知关闭了对话") case .recordLive: - SVProgressHUD.showInfo(withStatus: "请求开启现场录音") + YLprogressHUD.showAutoHiden("请求开启现场录音") case .recordCall: - SVProgressHUD.showInfo(withStatus: "请求开启通话录音") + YLprogressHUD.showAutoHiden("请求开启通话录音") case .si: - SVProgressHUD.showInfo(withStatus: "请求开启同传听译") + YLprogressHUD.showAutoHiden( "请求开启同传听译") case .chat: - SVProgressHUD.showInfo(withStatus: "通知开启了AI对话") + YLprogressHUD.showAutoHiden( "通知开启了AI对话") @unknown default: break } diff --git a/ShenYin/ShenYin/SceneDelegate.swift b/ShenYin/ShenYin/SceneDelegate.swift index a191bc1..c891392 100644 --- a/ShenYin/ShenYin/SceneDelegate.swift +++ b/ShenYin/ShenYin/SceneDelegate.swift @@ -20,7 +20,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { App.shared.window = window window?.rootViewController = BaseTC() - window?.rootViewController = UINavigationController(rootViewController: CustomEqVC()) + window?.rootViewController = UINavigationController(rootViewController: BleScanVC()) AppLaunch.start() } diff --git a/ShenYin/ShenYin/UI/Base/BaseTC.swift b/ShenYin/ShenYin/UI/Base/BaseTC.swift index 0ef49d6..06eddf7 100644 --- a/ShenYin/ShenYin/UI/Base/BaseTC.swift +++ b/ShenYin/ShenYin/UI/Base/BaseTC.swift @@ -55,6 +55,6 @@ class BaseTC:UITabBarController{ self.tabBar.backgroundColor = .white view.backgroundColor = .color(.bgColor) - self.selectedIndex = 1 + self.selectedIndex = 0 } } diff --git a/ShenYin/ShenYin/UI/Home/Chat/ChatCell.swift b/ShenYin/ShenYin/UI/Home/Chat/ChatCell.swift index 71cb86f..cfb25ea 100644 --- a/ShenYin/ShenYin/UI/Home/Chat/ChatCell.swift +++ b/ShenYin/ShenYin/UI/Home/Chat/ChatCell.swift @@ -8,11 +8,11 @@ public class ChatCellModel { public var type: Int = 0//1发,0收 public var content: String = "" - public var id:UInt = 0 + public var id:Int = 0 } class ChatCell:BaseTableViewCell{ - let bgView = UIView() + let bgView = LoadingView() let originalLabel = UILabel() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { @@ -54,13 +54,20 @@ class ChatCell:BaseTableViewCell{ make.top.bottom.equalToSuperview().inset(14) make.left.right.equalToSuperview().inset(12) make.width.lessThanOrEqualTo(kScreenWid - 60) + make.width.greaterThanOrEqualTo(60) + make.height.greaterThanOrEqualTo(19) } } var data:ChatCellModel!{ didSet{ if data.content.isEmpty{ - data.content = "..." + originalLabel.text = "" + bgView.startAnimating() + } + else{ + bgView.stopAnimating() + originalLabel.text = data.content } if data.type == 1 { bgView.backgroundColor = .color(.theme) @@ -80,7 +87,6 @@ class ChatCell:BaseTableViewCell{ make.left.equalToSuperview().inset(20) } } - originalLabel.text = data.content } } } diff --git a/ShenYin/ShenYin/UI/Home/Chat/ChatVC.swift b/ShenYin/ShenYin/UI/Home/Chat/ChatVC.swift index fda5200..bd3982b 100644 --- a/ShenYin/ShenYin/UI/Home/Chat/ChatVC.swift +++ b/ShenYin/ShenYin/UI/Home/Chat/ChatVC.swift @@ -134,7 +134,15 @@ class ChatVC:BaseVC{ extension ChatVC:ChatRecordBarDelegate{ func recordBarStart(_ toolBar: ChatRecordBar) { -// JoyGemChatManager.shared().playAudioEnd() + + let model = ChatCellModel() + model.type = 1 + model.content = "" + model.id = -1 + dataList.append(model) + tableView.reloadData() + scrollToBottom() + JoyGemChatManager.shared().stopChat() JoyGemChatManager.shared().startSingleChat() } @@ -199,20 +207,27 @@ extension ChatVC : JoyGemChatManagerDelegate { func chatManager(_ manager: JoyGemChatManager, requestText text: String?, index: UInt) { Logger.debug(text,index) - if let text = text { - if let model = dataList.last,model.id == index,model.type == 1 { - model.content = text - } - else{ - let model = ChatCellModel() - model.type = 1 - model.content = text - model.id = index - dataList.append(model) - } - tableView.reloadData() - scrollToBottom() + guard let text = text else{ + return + } + if text.isEmpty { + return + } + if dataList.last?.id == -1 { + dataList.removeLast() + } + if let model = dataList.last,model.id == index,model.type == 1 { + model.content = text + } + else{ + let model = ChatCellModel() + model.type = 1 + model.content = text + model.id = Int(index) + dataList.append(model) } + tableView.reloadData() + scrollToBottom() } func chatManager(_ manager: JoyGemChatManager, responseText text: String?, index: UInt, finish isFinish: Bool) { @@ -226,7 +241,7 @@ extension ChatVC : JoyGemChatManagerDelegate { let model = ChatCellModel() model.type = 0 model.content = text - model.id = index + model.id = Int(index) dataList.append(model) } tableView.reloadData() diff --git a/ShenYin/ShenYin/UI/Home/FieldRecording/FieldRecordBar.swift b/ShenYin/ShenYin/UI/Home/FieldRecording/FieldRecordBar.swift index 575baca..018aaaf 100644 --- a/ShenYin/ShenYin/UI/Home/FieldRecording/FieldRecordBar.swift +++ b/ShenYin/ShenYin/UI/Home/FieldRecording/FieldRecordBar.swift @@ -19,7 +19,7 @@ protocol FieldRecordBarDelegate { class FieldRecordBar: BaseView { - let recordBtn = UIButton() + let recordBtn = LoadingButton() let leftItem = RecordBarItem() let rightItem = RecordBarButton() var state:RecordSate = .stop diff --git a/ShenYin/ShenYin/UI/Home/FieldRecording/FieldRecordingVC.swift b/ShenYin/ShenYin/UI/Home/FieldRecording/FieldRecordingVC.swift index b7cc559..75a807a 100644 --- a/ShenYin/ShenYin/UI/Home/FieldRecording/FieldRecordingVC.swift +++ b/ShenYin/ShenYin/UI/Home/FieldRecording/FieldRecordingVC.swift @@ -86,14 +86,17 @@ extension FieldRecordingVC:FieldRecordBarDelegate{ } else if state == .stop{ JoyGemRecordManager.shared().stop() - - let v = PopTextField() - v.show() - v.cancelTap = { - - } - v.okTap = { - + bar.recordBtn.startAnimating {[weak self] in + guard let self = self else{return} +// toolBar.recordBtn.stopCli() + let v = PopTextField() + v.show() + v.cancelTap = { + + } + v.okTap = { + + } } } } @@ -144,12 +147,21 @@ extension FieldRecordingVC : JoyGemRecordManagerDelegate { func recordManagerStopped(_ manager: JoyGemRecordManager, reason code: JoyGemRecordStopCode) { -// if (code == .actively) { + if (code == .actively) { // YLprogressHUD.showAutoHiden("用户主动结束") -// } else { -// YLprogressHUD.showAutoHiden("自动结束") -// ///判断当前蓝牙是否连接从而确定是否因为蓝牙断开造成的录音断开 -// } +// toolBar.recordBtn.stopLoading() +// let v = PopTextField() +// v.show() +// v.cancelTap = { +// +// } +// v.okTap = { +// +// } + } else { + YLprogressHUD.showAutoHiden("自动结束") + ///判断当前蓝牙是否连接从而确定是否因为蓝牙断开造成的录音断开 + } } func recordManager(_ manager: JoyGemRecordManager, onError code: JoyGemErrorCode) { diff --git a/ShenYin/ShenYin/UI/Home/FieldRecording/RhythView.swift b/ShenYin/ShenYin/UI/Home/FieldRecording/RhythView.swift index 76371dd..2b837ad 100644 --- a/ShenYin/ShenYin/UI/Home/FieldRecording/RhythView.swift +++ b/ShenYin/ShenYin/UI/Home/FieldRecording/RhythView.swift @@ -1,5 +1,17 @@ import UIKit +//import DSWaveformImage -class RhythView: UIView { - +class RhythView: BaseView { +// let wave = WaveformLiveView(frame: CGRect(x: 0, y: 0, width: kScreenWid, height: 50)) +// +// override func setupViews() { +// backgroundColor = .red +// wave.backgroundColor = .green +// addSubview(wave) +// +// } +// override func setupLayout() { +// +// } + } diff --git a/ShenYin/ShenYin/UI/Mode/CustomEqVC.swift b/ShenYin/ShenYin/UI/Mode/CustomEqVC.swift index 184680f..870c17b 100644 --- a/ShenYin/ShenYin/UI/Mode/CustomEqVC.swift +++ b/ShenYin/ShenYin/UI/Mode/CustomEqVC.swift @@ -7,7 +7,6 @@ import UIKit import JoyGemAI -import MultiSlider class CustomEqVC:BaseVC{ private let bgView = UIView() private let sliderBgView = UIView() diff --git a/ShenYin/ShenYin/UI/Scan/BleScanVC.swift b/ShenYin/ShenYin/UI/Scan/BleScanVC.swift index 37dc8ea..aa11e6a 100644 --- a/ShenYin/ShenYin/UI/Scan/BleScanVC.swift +++ b/ShenYin/ShenYin/UI/Scan/BleScanVC.swift @@ -8,7 +8,15 @@ import UIKit import CoreBluetooth import DGActivityIndicatorView + +enum BleScanState{ + case scan + case has + case none +} + class BleScanVC: BaseVC{ + let headerView = BleScanHeaderView(frame: CGRect(x: 0, y: 0, width: kScreenWid, height: 280)) let tableView = UITableView(frame: .zero, style: .plain) var list:[CBPeripheral] = [] @@ -25,7 +33,7 @@ class BleScanVC: BaseVC{ v.estimatedRowHeight = 76 v.separatorStyle = .none v.register(BleScanCell.self, forCellReuseIdentifier: BleScanCell.reuseID) - v.tableHeaderView = BleScanHeaderView(frame: CGRect(x: 0, y: 0, width: kScreenWid, height: 280)) + v.tableHeaderView = headerView } view.addSubview(tableView) } @@ -39,6 +47,12 @@ class BleScanVC: BaseVC{ BleManager.shared.discoverDeviceCallback = {[weak self] devices in self?.list = devices self?.tableView.reloadData() + if devices.count > 0 { + self?.headerView.stateView.state = .has + } + else{ + self?.headerView.stateView.state = .none + } } startScan() } @@ -48,7 +62,7 @@ class BleScanVC: BaseVC{ func startScan(){ list = [] tableView.reloadData() - BleManager.shared.startScanDevice() + BleManager.shared.startScanDevice() } } @@ -72,10 +86,11 @@ extension BleScanVC:UITableViewDelegate,UITableViewDataSource { class BleScanHeaderView: BaseView { let rippleView = DGActivityIndicatorView(type: .triplePulse,tintColor: UIColor.hexString("#0092E1"),size: 250)! var radarImageView = UIImageView() + var stateView = ScanView() override func setupViews() { backgroundColor = .clear // rippleView.backgroundColor = .red - addSubviews([rippleView,radarImageView]) + addSubviews([rippleView,radarImageView,stateView]) rippleView.startAnimating() radarImageView.do { v in @@ -101,6 +116,58 @@ class BleScanHeaderView: BaseView { make.size.equalTo(250) make.center.equalToSuperview() } + stateView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalTo(rippleView.snp.bottom).offset(30) + } + } + + + + class ScanView: BaseView { + let titleLabel = UILabel() + let desLabel = UILabel() + var state:BleScanState = .scan{ + didSet{ + self.isHidden = state == .has + if state == .none { +// titleLabel.text = "正在扫描" +// desLabel.text = "请确保智能设备已连接电源,且位于手机附近" + } + else{ + titleLabel.text = "正在扫描" + desLabel.text = "请确保智能设备已连接电源,且位于手机附近" + } + } + } + override func setupViews() { + backgroundColor = .clear + addSubviews([titleLabel,desLabel]) + titleLabel.do { (v) in + v.textColor = .rgb(0x121212) + v.font = .regular(14) + v.textAlignment = .center + v.numberOfLines = 0 + } + desLabel.do { (v) in + v.textColor = .rgb(0x8D8D8D) + v.font = .regular(14) + v.textAlignment = .center + v.numberOfLines = 0 + } + } + override func setupLayout() { + titleLabel.snp.makeConstraints { make in + make.top.equalToSuperview() + make.centerX.equalToSuperview() + } + desLabel.snp.makeConstraints { make in + make.top.equalTo(titleLabel.snp.bottom).offset(10) + make.centerX.equalToSuperview() + } + } + + } } diff --git a/ShenYin/ShenYin/UI/common/LoadingButton.swift b/ShenYin/ShenYin/UI/common/LoadingButton.swift new file mode 100644 index 0000000..464b106 --- /dev/null +++ b/ShenYin/ShenYin/UI/common/LoadingButton.swift @@ -0,0 +1,60 @@ +// +// LoadingButton.swift +// ShenYin +// +// Created by liangshi on 2025/9/11. +// +import DGActivityIndicatorView +import UIKit +class LoadingButton:UIButton{ + let loadingView = DGActivityIndicatorView(type: .ballClipRotate,tintColor: UIColor.hexString("#0092E1"))! + + override init(frame: CGRect) { + super.init(frame: frame) + loadingView.backgroundColor = .white + addSubview(loadingView) + loadingView.snp.remakeConstraints { make in + make.edges.equalToSuperview() + } + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + func startAnimating(finished:(()->Void)? = nil){ + loadingView.startAnimating() + DispatchQueue.main.asyncAfter(deadline:.now() + 3) { + self.stopAnimating() + finished?() + } + } + func stopAnimating(){ + loadingView.stopAnimating() + } +} + +class LoadingView: UIView { + let activeView = DGActivityIndicatorView(type: .ballPulse,tintColor: .white)! + + override init(frame: CGRect) { + super.init(frame: frame) + activeView.backgroundColor = .clear + addSubview(activeView) + activeView.snp.makeConstraints { make in + make.center.equalToSuperview() + make.width.equalTo(60) + make.height.equalTo(40) + } + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func startAnimating(finished:(()->Void)? = nil){ + activeView.startAnimating() + } + func stopAnimating(){ + activeView.stopAnimating() + } +} diff --git a/ShenYin/ShenYin/UI/common/cache/CacheManager.swift b/ShenYin/ShenYin/UI/common/cache/CacheManager.swift new file mode 100644 index 0000000..5f2f202 --- /dev/null +++ b/ShenYin/ShenYin/UI/common/cache/CacheManager.swift @@ -0,0 +1,62 @@ +// +// c.swift +// ShenYin +// +// Created by liangshi on 2025/9/11. +// +import CoreBluetooth + +class CacheManager{ + static let shared = CacheManager() + var currentDevice:DeviceModel? + + func saveDevice(_ device: DeviceModel) { + self.currentDevice = device + DeviceCache.shared.saveDevice(device) + } +} + +class DeviceModel: NSObject, NSCoding { + var name = "" + var uuid = "" + + init(name: String, uuid: String) { + self.name = name + self.uuid = uuid + } + + func encode(with aCoder: NSCoder) { + aCoder.encode(name, forKey: "name") + aCoder.encode(uuid, forKey: "uuid") + } + + required init?(coder aDecoder: NSCoder) { + name = aDecoder.decodeObject(forKey: "name") as? String ?? "" + uuid = aDecoder.decodeObject(forKey: "uuid") as? String ?? "" + } +} + +class DeviceCache { + static let shared = DeviceCache() + private let userDefaults = UserDefaults.standard + private let deviceListKey = "deviceListKey" + + func saveDevice(_ device: DeviceModel) { + var deviceList = getDeviceList() + if let index = deviceList.firstIndex(where: { $0.uuid == device.uuid }) { + deviceList[index] = device + } else { + deviceList.append(device) + } + let encoder = NSKeyedArchiver.archivedData(withRootObject: deviceList) + userDefaults.set(encoder, forKey: deviceListKey) + } + + func getDeviceList() -> [DeviceModel] { + if let data = userDefaults.data(forKey: deviceListKey), + let deviceList = NSKeyedUnarchiver.unarchiveObject(with: data) as? [DeviceModel] { + return deviceList + } + return [] + } +} diff --git a/ShenYin/ShenYin/UI/common/pop/ConnectPopView.swift b/ShenYin/ShenYin/UI/common/pop/ConnectPopView.swift new file mode 100644 index 0000000..82879e3 --- /dev/null +++ b/ShenYin/ShenYin/UI/common/pop/ConnectPopView.swift @@ -0,0 +1,86 @@ +// +// ConnectPopView.swift +// ShenYin +// +// Created by liangshi on 2025/9/11. +// + +import UIKit + +class ConnectPopView: BasePresentView2 { + let contentView = UIView() + private let titleLabel = UILabel() + private let imageView = UIImageView() + private let desLabel = UILabel() + + + init() { + super.init() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func setupSubView() { + super.setupSubView() + addSubview(contentView) + contentView.addSubviews([titleLabel,imageView,desLabel]) + } + override func setupLayout() { + super.setupLayout() + + contentView.snp.makeConstraints { make in + make.left.right.equalToSuperview().inset(18) + make.height.equalTo(315) + make.center.equalToSuperview() + } + titleLabel.snp.makeConstraints { (m) in + m.top.equalToSuperview().inset(30) + m.left.right.equalToSuperview() + } + imageView.snp.makeConstraints { (m) in + m.centerX.equalToSuperview() + m.top.equalToSuperview().inset(76) + m.width.equalTo(190) + m.height.equalTo(156) + } + desLabel.snp.makeConstraints { (m) in + m.top.equalTo(imageView.snp.bottom).offset(20) + m.left.right.equalToSuperview() +// m.bottom.equalToSuperview().inset(30) + } + } + + override func setupStyle() { + super.setupStyle() + contentView.do { (v) in + v.backgroundColor = .white + v.yc.setCornerRadius(20) + } + imageView.do { v in + v.image = UIImage(named: "home_header") + } + titleLabel.do { (v) in + v.textColor = .rgb(0x121212) + v.font = .regular(20) + v.textAlignment = .center + v.text = "Deep Gen2 Max" + } + desLabel.do { (v) in + v.textColor = .rgb(0x121212) + v.font = .regular(24) + v.textAlignment = .center + v.text = "连接成功" + } + } + + func showAutoHide(finished: (() -> Void)? = nil){ + show() + DispatchQueue.main.asyncAfter(deadline:.now() + 0.5) { + self.hide() + finished?() + } + } +} + diff --git a/ShenYin/podfile b/ShenYin/podfile index 55c4a07..fee0b8d 100644 --- a/ShenYin/podfile +++ b/ShenYin/podfile @@ -32,7 +32,9 @@ target 'ShenYin' do pod 'SocketRocket'#socket,AI用到 pod 'DGActivityIndicatorView'#扫描雷达 - pod 'MultiSlider' +# pod 'MultiSlider' +# pod 'DSWaveformImage' + # pod 'NVActivityIndicatorView', '~> 5.1.1' # 最新稳定版 # pod 'EZAudio', '~> 1.1.0' end