- 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)
- 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)
- Kingfisher (~> 6.0)
- MJRefresh
- Moya
+ - MultiSlider
- netfox
- RealmSwift
- SnapKit
- Kingfisher
- MJRefresh
- Moya
+ - MultiSlider
- netfox
- Realm
- RealmSwift
- SnapKit
- SocketRocket
- SVProgressHUD
+ - SweeterSwift
- SwiftDate
- swiftScan
- TabPageViewController
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
YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30
YYText: 5c461d709e24d55a182d1441c41dc639a18a4849
-PODFILE CHECKSUM: 3ae5b0826c9764636aac77b04720df3c8e87c203
+PODFILE CHECKSUM: 826428f9bd4197f6e9759f68eaf9008f80c0563b
COCOAPODS: 1.16.2
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";
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = demo.ShenYin;
+ PRODUCT_BUNDLE_IDENTIFIER = com.deepchords.app;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = demo.ShenYin;
+ PRODUCT_BUNDLE_IDENTIFIER = com.deepchords.app;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "Group_2377.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group_2377@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group_2377@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "Group_2374.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group_2374@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group_2374@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "Group_2378.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group_2378@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group_2378@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "Group_2382.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group_2382@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group_2382@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "默认.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "默认@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "默认@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "Group_2383.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group_2383@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group_2383@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "Group_2376.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group_2376@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group_2376@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "Group 2375.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group 2375@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group 2375@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "Group_2379.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group_2379@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group_2379@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "Group_2380.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group_2380@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group_2380@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "Group_2381.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group_2381@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group_2381@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Frame_1938@2x(4).png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Frame_1938@3x(4).png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Frame_1938@2x(1).png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Frame_1938@3x(1).png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Frame_1938@2x(2).png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Frame_1938@3x(2).png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
"scale" : "1x"
},
{
- "filename" : "Group_2361@2x.png",
+ "filename" : "Frame_1938@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
- "filename" : "Group_2361@3x.png",
+ "filename" : "Frame_1938@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Frame_1938@2x(3).png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Frame_1938@3x(3).png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "中英互译@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "中英互译@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "对话翻译@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "对话翻译@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "同传听译@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "同传听译@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "Frame_2259.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Frame_2259@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Frame_2259@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "filename" : "Frame_2260.png",
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Frame_2260@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Frame_2260@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Frame@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Frame@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Frame@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Frame@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Group 1390@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Group 1390@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Frame_2257@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Frame_2257@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+ <device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
+ <capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
- <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
+ <subviews>
+ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="launch_1" translatesAutoresizingMaskIntoConstraints="NO" id="8TX-Ve-nzh">
+ <rect key="frame" x="152.66666666666666" y="298" width="88" height="80"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="80" id="DNK-i3-D42"/>
+ <constraint firstAttribute="width" constant="88" id="EyO-1D-4e6"/>
+ </constraints>
+ </imageView>
+ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="launch_2" translatesAutoresizingMaskIntoConstraints="NO" id="L2B-xq-w7f">
+ <rect key="frame" x="174.66666666666666" y="645" width="44" height="26"/>
+ <constraints>
+ <constraint firstAttribute="height" constant="26" id="4X4-Wo-adV"/>
+ <constraint firstAttribute="width" constant="44" id="luP-1Q-Shi"/>
+ </constraints>
+ </imageView>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="让AI更懂你" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Cp5-00-8Vg">
+ <rect key="frame" x="153" y="681" width="87" height="21"/>
+ <fontDescription key="fontDescription" type="system" pointSize="17"/>
+ <nil key="textColor"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
+ <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+ <constraints>
+ <constraint firstItem="8TX-Ve-nzh" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="25Q-jH-Ved"/>
+ <constraint firstItem="8TX-Ve-nzh" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="180" id="Hvr-8h-kxK"/>
+ <constraint firstItem="Cp5-00-8Vg" firstAttribute="top" secondItem="L2B-xq-w7f" secondAttribute="bottom" constant="10" id="Jsm-db-lDG"/>
+ <constraint firstItem="L2B-xq-w7f" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="e8l-2p-vh6"/>
+ <constraint firstItem="Cp5-00-8Vg" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="gKu-6O-lfY"/>
+ <constraint firstAttribute="bottom" secondItem="Cp5-00-8Vg" secondAttribute="bottom" constant="150" id="uAy-il-pd2"/>
+ </constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
- <point key="canvasLocation" x="53" y="375"/>
+ <point key="canvasLocation" x="52.671755725190835" y="374.64788732394368"/>
</scene>
</scenes>
+ <resources>
+ <image name="launch_1" width="88" height="80"/>
+ <image name="launch_2" width="44" height="26"/>
+ <systemColor name="systemBackgroundColor">
+ <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+ </systemColor>
+ </resources>
</document>
if (service.uuid.uuidString == kJoyGemAIServiceUUID) {
let success = JoyGemAIManager.shared().configService(service) { chars in
for char in chars {
- debugPrint(char)
+ Logger.debug(char)
peripheral.setNotifyValue(true, for: char)
}
}
if (!success) {
- debugPrint("初始化失败!")
+ Logger.debug("初始化失败!")
}
}
}
case .recordCall:
SVProgressHUD.showInfo(withStatus: "请求开启通话录音")
case .si:
- SVProgressHUD.showInfo(withStatus: "请求开启同声传译")
+ SVProgressHUD.showInfo(withStatus: "请求开启同传听译")
case .chat:
SVProgressHUD.showInfo(withStatus: "通知开启了AI对话")
@unknown default:
<string>bluetooth-central</string>
<string>audio</string>
</array>
+ <key>CFBundleDisplayName</key>
+ <string>深音</string>
</dict>
</plist>
App.shared.window = window
window?.rootViewController = BaseTC()
- window?.rootViewController = UINavigationController(rootViewController: FieldRecordingVC())
+ window?.rootViewController = UINavigationController(rootViewController: CustomEqVC())
AppLaunch.start()
}
/// e.g. 2020年01月01日 01:01:01.088
static let full1: Format = .init("yyyy年MM月dd日 HH:mm:ss.SSS")
+ static let full2: Format = .init("yyyy-MM-ddTHH:mm")
+ static let full3: Format = .init("yyyy-MM-dd HH:mm")
}
/// 格式化成本地时间
self.tabBar.backgroundColor = .white
view.backgroundColor = .color(.bgColor)
- self.selectedIndex = 0
+ self.selectedIndex = 1
}
}
+++ /dev/null
-//
-// GlobalConfig.swift
-// ShenYin
-//
-// Created by liangshi on 2025/8/27.
-//
-
-class GlobalConfig{
- static let languages = ["简体中文","English","日语","法语"]
- static let tranlateLanguages = [
- "中文",
- "英文",
- "日文",
- "韩文",
- "法文",
- "西班牙文",
- "葡萄牙文",
- "印度尼西亚",
- "俄文",
- "马来文",
- ]
-}
}
override func setupViews() {
navBar.title = "通话录音"
- navBar.rightView.setImage(UIImage(named: "help_icon"), for: .normal)
-
textView.do { v in
- v.text = "好优美的一篇文章,山花落尽,我心犹青|||记得春日时分,山花绽放得那样热烈,鲜红的、明黄的、洁白的,仿佛将整片山野染成了一幅画。那时的心也如山花般明亮,轻快地跳跃在生活的每一个角落。然而,繁华易逝,花朵终会飘落。花落的那天,我站在同一片山坡上,听着风带走它们的碎影。那种空落感从心底涌起,像极了许多未能言说的遗憾,带着些许酸涩。"
+ v.isEditable = false
v.font = .regular(14)
v.textColor = .hexString("#121212")
v.contentInset = UIEdgeInsets(top: 0, left: 18, bottom: 0, right: 18)
make.left.right.equalToSuperview()
make.bottom.equalTo(toolBar.snp.top)
}
- }
- override func navRightViewTapped() {
-
}
func scrollToBottom(){
//
/// Ai回应模型
public class ChatCellModel {
- public var type: Int = 0
+ public var type: Int = 0//1发,0收
public var content: String = ""
public var id:UInt = 0
}
}
originalLabel.snp.makeConstraints { make in
- make.left.right.top.bottom.equalToSuperview().inset(10)
- make.width.lessThanOrEqualTo(kScreenWid - 56)
+ make.top.bottom.equalToSuperview().inset(14)
+ make.left.right.equalToSuperview().inset(12)
+ make.width.lessThanOrEqualTo(kScreenWid - 60)
}
}
//
// Created by liangshi on 2025/9/3.
//
-
+import JoyGemAI
+import UIKit
class ChatHeaderView: BaseView {
let icon = UIImageView()
let titleLabel = UILabel()
let desLabel = UILabel()
+ var role:JoyGemSpeaker!{
+ didSet{
+// titleLabel.text = role.name
+ icon.image = UIImage(named: "role_" + role.role)
+ }
+ }
override func setupViews() {
// backgroundColor = .red
v.image = UIImage(named: "chat_xiaoyin")
}
titleLabel.do {v in
- v.text = "嗨!我是小音"
+// v.text = "嗨!我是小音"
v.numberOfLines = 0
v.textAlignment = .center
v.textColor = .hexString("#121212")
v.font = .bold(18)
}
desLabel.do {v in
- v.text = "我可以帮你搜索、答疑、写作,请把你的任务交给 我吧~"
+// v.text = "我可以帮你搜索、答疑、写作,请把你的任务交给 我吧~"
v.numberOfLines = 0
v.textAlignment = .center
v.textColor = .hexString("#666666")
}
}
override func setupData() {
- JoyGemChatManager.shared().getSpeakerList {[weak self] speakers in
- guard let self = self,speakers.count > 0 else{return}
- self.roleList = speakers
- self.roleItem.role = speakers.first
- JoyGemChatManager.shared().setSpeaker(self.roleItem.role)
- }
-
JoyGemChatManager.shared().delegate = self
PcmSound.sharedInstance().delegate = self
JoyGemChatManager.shared().addObserver(self, forKeyPath: "isActive",options: [.new, .old], context: nil);
+
+ let model = ChatCellModel()
+ model.type = 0
+ model.content = "我是你的新朋友,有什么我可以帮助到你的?"
+ model.id = 0
+ dataList.append(model)
+
+ loadRoleList()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
App.shared.goToPage(IntelligentVC())
}
@objc func roleBtnAction(){
+ if roleList.count == 0 {
+ loadRoleList()
+ return
+ }
let vc = RoleListVC(list: roleList, selectedModel: roleItem.role) {[weak self] model in
guard let self = self else{return}
roleItem.role = model
+ headerView.role = model
JoyGemChatManager.shared().setSpeaker(model)
}
App.shared.goToPage(vc)
tableView.scrollToRow(at: IndexPath(row: dataList.count - 1, section: 0), at: .none, animated: true)
}
}
+ func loadRoleList(){
+ JoyGemChatManager.shared().getSpeakerList {[weak self] speakers in
+ guard let self = self,speakers.count > 0 else{return}
+ self.roleList = speakers
+ self.roleItem.role = speakers.first
+ self.headerView.role = speakers.first
+ JoyGemChatManager.shared().setSpeaker(self.roleItem.role)
+ }
+ }
}
extension ChatVC:ChatRecordBarDelegate{
var role:JoyGemSpeaker!{
didSet{
titleLabel.text = role.name
+ icon.image = UIImage(named: "role_" + role.role)
}
}
var data:JoyGemSpeaker!{
didSet{
titleLabel.text = data.name
+ icon.image = UIImage(named: "role_" + data.role)
}
}
}
}
override func navRightViewTapped() {
-
+ let tip = RecordTipsView(type: .chinese2english)
+ tip.show()
}
func scrollToBottom(){
if dataList.count > 0 {
}
}
override func navRightViewTapped() {
-
+ let tip = RecordTipsView(type: .dialog)
+ tip.show()
}
func scrollToBottom(){
if dataList.count > 0 {
}
protocol FieldRecordBarDelegate {
- func fieldRecordBar(_ bar:FieldRecordBar,languageChange language:String)
+ func fieldRecordBar(_ bar:FieldRecordBar,languageChange language:AiSupportLanguage)
func fieldRecordBar(_ bar:FieldRecordBar,stateChange state:RecordSate)
}
let leftItem = RecordBarItem()
let rightItem = RecordBarButton()
var state:RecordSate = .stop
-
-// var languageDidChange:((String)->Void)?
-// var recordStateDidChange:((RecordSate)->Void)?
var delegate:FieldRecordBarDelegate?
override func setupViews() {
}
leftItem.do {v in
v.yc.addTap(target: self, action: #selector(leftAction))
+ v.language = .chinse
}
rightItem.do {v in
v.state = .stop
if recordBtn.isSelected {
return
}
- let v = CustomPicker(title: "请选择语言", list: GlobalConfig.languages)
- v.selectedIndex = 0
+ let list = AiSupportLanguage.record.map{$0.title}
+
+ let v = CustomPicker(title: "请选择语言", list:list )
+ v.selectedIndex = list.firstIndex(where: {leftItem.language.title == $0})!
v.show()
v.didSelected = {[weak self] (index,value) in
guard let self = self else { return }
- leftItem.titleLabel.text = value
- delegate?.fieldRecordBar(self, languageChange:value)
+ leftItem.language = AiSupportLanguage.record.first(where: {$0.title == value})!
+ delegate?.fieldRecordBar(self, languageChange:leftItem.language)
}
return
}
}
class RecordBarItem: BaseView {
- let icon = UIImageView()
- let titleLabel = UILabel()
+ private let icon = UIImageView()
+ private let titleLabel = UILabel()
+ var language:AiSupportLanguage = .chinse{
+ didSet{
+ titleLabel.text = language.title
+ }
+ }
override func setupViews() {
addSubviews([titleLabel,icon])
icon.do { v in
titleLabel.do { v in
v.textColor = .rgb(0x121212)
v.font = .regular(10)
- v.text = "中文"
}
}
}
override func setupViews() {
navBar.title = "现场录音"
- navBar.rightView.setImage(UIImage(named: "help_icon"), for: .normal)
toolBar.delegate = self
textView.do { v in
+ v.isEditable = false
v.font = .regular(14)
v.text = ""
v.textColor = .hexString("#121212")
} catch {
print(error)
}
- }
- override func navRightViewTapped() {
-
}
func scrollToBottom(){
}
extension FieldRecordingVC:FieldRecordBarDelegate{
- func fieldRecordBar(_ bar: FieldRecordBar, languageChange language: String) {
-
+ func fieldRecordBar(_ bar: FieldRecordBar, languageChange language: AiSupportLanguage) {
+ JoyGemRecordManager.shared().originalLanguage = language.value
}
func fieldRecordBar(_ bar: FieldRecordBar, stateChange state: RecordSate) {
if state == .start {
textView.text = ""
messageList.removeAll()
- JoyGemRecordManager.shared().originalLanguage = kJoyGemAILocalizationZH
JoyGemRecordManager.shared().start()
}
if state == .resume{
}
func recordManager(_ manager: JoyGemRecordManager, didUpdateAsr model: JoyGemAsrModel) {
- debugPrint("text: \(model.text),index: \(model.index)")
+ Logger.debug("text: \(model.text),index: \(model.index)")
let msg = messageList.firstIndex (where: { (str,idx) in
return idx == model.index;
})
func recordManager(_ manager: JoyGemRecordManager, update mode: JoyGemRecordMode) {
- debugPrint("mode: \(mode)")
+ Logger.debug("mode: \(mode)")
}
func recordManager(_ manager: JoyGemRecordManager, saveFile path: String) {
- debugPrint("path: \(path)")
+ Logger.debug("path: \(path)")
recordFilePath = path
}
func recordManager(_ manager: JoyGemRecordManager, stateChange code: JoyGemStateCode) {
- debugPrint("code: \(code)")
+ Logger.debug("code: \(code)")
}
func recordManagerStopped(_ manager: JoyGemRecordManager, reason code: JoyGemRecordStopCode) {
- if (code == .actively) {
- YLprogressHUD.showAutoHiden("用户主动结束")
- } else {
- YLprogressHUD.showAutoHiden("自动结束")
- ///判断当前蓝牙是否连接从而确定是否因为蓝牙断开造成的录音断开
- }
+// if (code == .actively) {
+// YLprogressHUD.showAutoHiden("用户主动结束")
+// } else {
+// YLprogressHUD.showAutoHiden("自动结束")
+// ///判断当前蓝牙是否连接从而确定是否因为蓝牙断开造成的录音断开
+// }
}
func recordManager(_ manager: JoyGemRecordManager, onError code: JoyGemErrorCode) {
extension FieldRecordingVC : PcmSoundDelegate {
func remaining(_ frames: UInt) {
- debugPrint("[frame:\(frames)]");
+ Logger.debug("[frame:\(frames)]");
}
}
--- /dev/null
+//
+// RecordDetailBar.swift
+// ShenYin
+//
+// Created by liangshi on 2025/9/5.
+//
+
+protocol RecordDetailBarDelegate {
+ func recordDetailBarTranstlateAction(_ bar:RecordDetailBar)
+ func recordDetailBarRenameAction(_ bar:RecordDetailBar)
+ func recordDetailBarPlayAction(_ bar:RecordDetailBar)
+ func recordDetailBarMoreAction(_ bar:RecordDetailBar)
+}
+
+class RecordDetailBar: BaseView {
+ let tranlateItem = RecordDetailBarButton()
+ let renameItem = RecordDetailBarButton()
+ let playItem = RecordDetailBarButton()
+ let moreItem = RecordDetailBarButton()
+
+ var delegate:RecordDetailBarDelegate?
+
+ override func setupViews() {
+ backgroundColor = .white
+ addSubviews([tranlateItem,renameItem,playItem,moreItem])
+
+ tranlateItem.do {v in
+ v.yc.addTap(target: self, action: #selector(tralateAction))
+ v.image = UIImage(named: "record_translate")
+ v.title = "翻译"
+ }
+ renameItem.do {v in
+ v.yc.addTap(target: self, action: #selector(renameAction))
+ v.image = UIImage(named: "record_rename")
+ v.title = "重命名"
+ }
+ playItem.do {v in
+ v.yc.addTap(target: self, action: #selector(playAction))
+ v.image = UIImage(named: "record_play 1")
+ v.title = "播放录音"
+ }
+ moreItem.do {v in
+ v.yc.addTap(target: self, action: #selector(moreAction))
+ v.image = UIImage(named: "record_more")
+ v.title = "更多"
+ }
+ }
+
+ override func setupLayout() {
+ let w = (kScreenWid - 40)/4
+ tranlateItem.snp.makeConstraints { make in
+ make.width.equalTo(w)
+ make.top.equalToSuperview()
+ make.height.equalTo(95)
+ make.left.equalToSuperview().inset(20)
+ }
+ renameItem.snp.makeConstraints { make in
+ make.width.equalTo(w)
+ make.top.height.equalTo(tranlateItem)
+ make.left.equalTo(tranlateItem.snp.right)
+ }
+ playItem.snp.makeConstraints { make in
+ make.width.equalTo(w)
+ make.top.height.equalTo(tranlateItem)
+ make.left.equalTo(renameItem.snp.right)
+ }
+ moreItem.snp.makeConstraints { make in
+ make.width.equalTo(w)
+ make.top.height.equalTo(tranlateItem)
+ make.left.equalTo(playItem.snp.right)
+ }
+ }
+ @objc func tralateAction(){
+ delegate?.recordDetailBarTranstlateAction(self)
+ }
+ @objc func renameAction(){
+ delegate?.recordDetailBarRenameAction(self)
+ }
+ @objc func playAction(){
+ delegate?.recordDetailBarPlayAction(self)
+ }
+ @objc func moreAction(){
+ delegate?.recordDetailBarMoreAction(self)
+ }
+
+ class RecordDetailBarButton: BaseView {
+ let icon = UIImageView()
+ let titleLabel = UILabel()
+ var image:UIImage!{
+ didSet{
+ icon.image = image
+ }
+ }
+ var title:String!{
+ didSet{
+ titleLabel.text = title
+ }
+ }
+
+ override func setupViews() {
+// backgroundColor = .red
+ addSubviews([titleLabel,icon])
+ icon.do { v in
+ }
+ titleLabel.do { v in
+ v.textColor = .rgb(0x232323)
+ v.font = .regular(10)
+ }
+ }
+
+ override func setupLayout() {
+ icon.snp.makeConstraints { make in
+ make.size.equalTo(30)
+ make.top.equalToSuperview().inset(16)
+ make.centerX.equalToSuperview()
+ }
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalTo(icon.snp.bottom).offset(5)
+ make.centerX.equalTo(icon)
+ }
+ }
+ }
+}
--- /dev/null
+//
+// Untitled.swift
+// ShenYin
+//
+// Created by liangshi on 2025/9/5.
+//
+
+protocol RecordDetailTopBarDelegate {
+ func recordDetailBarTranstlateAction(_ bar:RecordDetailTopBar)
+ func recordDetailTopBarOgrinAction(_ bar:RecordDetailTopBar)
+}
+
+class RecordDetailTopBar: BaseView {
+ let tranlateItem = LanguageItem()
+ let originItem = LanguageItem()
+
+
+ var delegate:RecordDetailTopBarDelegate?
+
+ override func setupViews() {
+ backgroundColor = .clear
+ addSubviews([tranlateItem,originItem])
+
+ tranlateItem.do {v in
+ v.yc.addTap(target: self, action: #selector(tralateAction))
+ v.label.text = "译文"
+ v.isSelected = false
+ }
+ originItem.do {v in
+ v.yc.addTap(target: self, action: #selector(originAction))
+ v.label.text = "原文"
+ v.isSelected = true
+ }
+ }
+
+ override func setupLayout() {
+ originItem.snp.makeConstraints { make in
+ make.width.equalTo(100)
+ make.top.equalToSuperview()
+ make.height.equalTo(36)
+ make.right.equalToSuperview().inset(kScreenWid/2 + 15)
+ }
+ tranlateItem.snp.makeConstraints { make in
+ make.width.equalTo(100)
+ make.top.equalToSuperview()
+ make.height.equalTo(36)
+ make.left.equalToSuperview().offset(kScreenWid/2 + 15)
+ }
+ }
+ @objc func tralateAction(){
+ tranlateItem.isSelected = !tranlateItem.isSelected
+ delegate?.recordDetailBarTranstlateAction(self)
+ }
+ @objc func originAction(){
+ originItem.isSelected = !originItem.isSelected
+ delegate?.recordDetailTopBarOgrinAction(self)
+ }
+
+
+ class LanguageItem: BaseView {
+ let label = UILabel()
+ var isSelected:Bool = false{
+ didSet{
+ if isSelected {
+ label.textColor = .hexString("#0092E1")
+ label.yc.setBorder(width: 2, color: .hexString("#0092E1"), radius: 8)
+ }
+ else{
+ label.textColor = .hexString("#121212")
+ label.yc.setBorder(width: 0, color: .hexString("#121212"), radius: 8)
+ }
+ }
+ }
+
+ override func setupViews() {
+ addSubviews([label])
+ label.do { (v) in
+ v.font = .medium(14)
+ v.textAlignment = .center
+ v.backgroundColor = .white
+ v.textColor = .hexString("#0092E1")
+ }
+ }
+
+ override func setupLayout() {
+ label.snp.makeConstraints { (m) in
+ m.edges.equalToSuperview()
+ }
+ }
+ }
+}
--- /dev/null
+//
+// RecordDetailVC.swift
+// ShenYin
+//
+// Created by liangshi on 2025/9/5.
+//
+
+import UIKit
+import JoyGemAI
+import AVFAudio
+class RecordDetailVC:BaseVC{
+ let timeLabel = UILabel()
+ let topBar = RecordDetailTopBar()
+ let toolBar = RecordDetailBar()
+ let textView = UITextView()
+ var messageList : [(String,UInt)] = []
+ var recordFilePath : String?
+
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ }
+ override func setupViews() {
+ navBar.title = "现场录音"
+ navBar.rightView.setImage(UIImage(named: "help_icon"), for: .normal)
+ toolBar.delegate = self
+ topBar.delegate = self
+
+ timeLabel.do { (v) in
+ v.font = .regular(14)
+ v.textAlignment = .center
+ v.textColor = .hexString("#666666")
+ v.text = Date().format(.full3)
+ }
+ textView.do { v in
+ v.font = .regular(14)
+ v.text = ""
+ v.textColor = .hexString("#121212")
+ v.contentInset = UIEdgeInsets(top: 0, left: 18, bottom: 0, right: 18)
+ }
+ view.addSubviews([timeLabel,topBar,textView,toolBar])
+
+ }
+ override func setupLayout() {
+ timeLabel.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.height.equalTo(36)
+ make.top.equalToSuperview().inset(kNavBtm )
+ }
+ topBar.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.height.equalTo(36)
+ make.top.equalTo(timeLabel.snp.bottom).offset(5)
+ }
+ toolBar.snp.makeConstraints { make in
+ make.width.centerX.equalToSuperview()
+ make.height.equalTo(95)
+ make.bottom.equalToSuperview().inset(20)
+ }
+ textView.snp.makeConstraints { make in
+ make.top.equalTo(topBar.snp.bottom)
+ make.left.right.equalToSuperview()
+ make.bottom.equalTo(toolBar.snp.top)
+ }
+ }
+ override func setupData() {
+ PcmSound.sharedInstance().delegate = self;
+ 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)
+ }
+ }
+ override func navRightViewTapped() {
+
+ }
+ func scrollToBottom(){
+
+ }
+}
+extension RecordDetailVC:RecordDetailTopBarDelegate{
+ func recordDetailBarTranstlateAction(_ bar: RecordDetailTopBar) {
+
+ }
+
+ func recordDetailTopBarOgrinAction(_ bar: RecordDetailTopBar) {
+
+ }
+}
+extension RecordDetailVC:RecordDetailBarDelegate{
+ func recordDetailBarTranstlateAction(_ bar: RecordDetailBar) {
+
+ }
+
+ func recordDetailBarRenameAction(_ bar: RecordDetailBar) {
+
+ }
+
+ func recordDetailBarPlayAction(_ bar: RecordDetailBar) {
+
+ }
+
+ func recordDetailBarMoreAction(_ bar: RecordDetailBar) {
+
+ }
+}
+
+extension RecordDetailVC : PcmSoundDelegate {
+
+ func remaining(_ frames: UInt) {
+ Logger.debug("[frame:\(frames)]");
+ }
+}
super.viewDidLoad()
}
override func setupViews() {
- navBar.title = "同声传译"
+ navBar.title = "同传听译"
navBar.rightView.setImage(UIImage(named: "help_icon"), for: .normal)
}
}
override func navRightViewTapped() {
-
+ let tip = RecordTipsView(type: .tongchuan)
+ tip.show()
}
func scrollToBottom(){
if dataList.count > 0 {
case .chinese2English:
return "中英互译"
case .recordTranslate:
- return "同声传译"
+ return "同传听译"
case .dialogTranslate:
return "对话翻译"
case .textTranslate:
}
override func setupViews() {
self.navBar.title = "文本翻译"
- navBar.rightView.setImage(UIImage(named: "help_icon"), for: .normal)
-
+ tableView.keyboardDismissMode = .onDrag
tableView.backgroundColor = .clear
tableView.delegate = self
tableView.dataSource = self
make.left.right.equalToSuperview()
make.bottom.equalTo(toolBar.snp.top)
}
- }
- override func navRightViewTapped() {
-
}
func scrollToBottom(){
if dataList.count > 0 {
tableView.reloadData()
scrollToBottom()
- let from = kJoyGemAILocalizationZH
- let to = kJoyGemAILocalizationEN
+ let from = languageItem.leftLabel.language.value
+ let to = languageItem.rightLabel.language.value
JoyGemAIManager.shared().translate(text, from: from, to: to) {[weak self] result, finish in
guard let self = self else{return}
if !finish{
dataList.last!.response = dataList.last!.response + result
tableView.reloadData()
+ scrollToBottom()
}
} error: { error in
--- /dev/null
+//
+// CustomEqVC.swift
+// ShenYin
+//
+// Created by liangshi on 2025/9/9.
+//
+
+import UIKit
+import JoyGemAI
+import MultiSlider
+class CustomEqVC:BaseVC{
+ private let bgView = UIView()
+ private let sliderBgView = UIView()
+ private let resetBtn = UIButton(type: .custom)
+ private let titleLabel = UILabel()
+ private let unitLabel = UILabel()
+ private let valueLabel1 = UILabel()
+ private let valueLabel2 = UILabel()
+ private let valueLabel3 = UILabel()
+ private var list:[EqSlider] = []
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ }
+
+ override func setupViews() {
+ self.navBar.title = "自定义音效"
+ navBar.backgroundColor = .white
+ view.addSubview(bgView)
+ bgView.addSubviews([sliderBgView])
+ bgView.addSubviews([resetBtn,titleLabel,unitLabel,valueLabel1,valueLabel2,valueLabel3])
+
+ bgView.do { v in
+ v.backgroundColor = .white
+ v.yc.setCornerRadius(12)
+ }
+ sliderBgView.do { v in
+// v.backgroundColor = .yellow
+ v.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
+ }
+ titleLabel.do { v in
+ v.text = "音效风格"
+ v.textColor = .hexString("#121212")
+ v.textAlignment = .left
+ v.font = .regular(14)
+ }
+ unitLabel.do { v in
+ v.text = "dp"
+ v.textColor = .hexString("#999999")
+ v.textAlignment = .left
+ v.font = .regular(12)
+ }
+ valueLabel1.do { v in
+ v.text = "+12"
+ v.textColor = .hexString("#999999")
+ v.textAlignment = .left
+ v.font = .regular(12)
+ }
+ valueLabel2.do { v in
+ v.text = "0"
+ v.textColor = .hexString("#999999")
+ v.textAlignment = .left
+ v.font = .regular(12)
+ }
+ valueLabel3.do { v in
+ v.text = "-12"
+ v.textColor = .hexString("#999999")
+ v.textAlignment = .left
+ v.font = .regular(12)
+ }
+ resetBtn.do { v in
+ v.contentMode = .center
+ v.setImage(UIImage(named: "mode_reset"), for: .normal)
+ v.addTarget(self, action: #selector(resetAction), for: .touchUpInside)
+ }
+ }
+ override func setupLayout() {
+
+ bgView.snp.makeConstraints { make in
+ make.width.equalTo(kScreenWid - 36)
+ make.height.equalTo(330)
+ make.centerX.equalToSuperview()
+ make.top.equalToSuperview().inset(kNavBtm + 30)
+ }
+ resetBtn.snp.makeConstraints { make in
+ make.top.equalToSuperview()
+ make.right.equalToSuperview()
+ make.size.equalTo(40)
+ }
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(12)
+ make.left.equalToSuperview().inset(12)
+ }
+ unitLabel.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(65)
+ make.left.equalToSuperview().inset(12)
+ }
+ valueLabel1.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(100)
+ make.left.equalToSuperview().inset(10)
+ }
+ valueLabel2.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(190)
+ make.left.equalTo(valueLabel1)
+ }
+ valueLabel3.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(280)
+ make.left.equalTo(valueLabel1)
+ }
+ sliderBgView.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(0)
+ make.right.equalToSuperview().inset(10)
+ make.top.equalToSuperview().inset(0)
+ make.bottom.equalToSuperview().inset(0)
+ }
+
+ let values = ["32","64","125","250","500","1k","2k","4k","8k","16k"]
+ let start = 30
+ let w = (Int(kScreenWid) - 36 - start)/10
+ for i in 0...9 {
+ let slider = EqSlider()
+ slider.index = i
+ slider.valueChange = { [weak self] (index,value) in
+ self?.sliderValueChange(index: index, value: value)
+ }
+ slider.titleLabel.text = values[i]
+ sliderBgView.addSubview(slider)
+ list.append(slider)
+ slider.snp.makeConstraints { make in
+ make.width.equalTo(300)
+ make.height.equalTo(30)
+ make.top.equalTo(i*w + start)
+ make.left.equalToSuperview()
+ }
+ }
+ }
+
+ override func setupData() {
+ JoyGemAIManager.shared().device.getCustomEQ {[weak self] eq in
+ Logger.debug("getCustomEQ:\(eq)");
+ self?.resetSlider(eq.bands)
+ } error: { err in
+ Logger.debug("getCustomEQ:\(err)");
+ }
+ }
+
+ @objc func resetAction(){
+ for item in list {
+ item.slider.setValue(0, animated: false)
+ }
+ JoyGemAIManager.shared().device.resetCustomEQ { err in
+ Logger.debug("setEQMode:\(err)");
+ }
+ }
+ @objc func sliderValueChange(index:Int,value:Int){
+ JoyGemAIManager.shared().device.setCustomEQ(UInt(index), withGain: value) { err in
+ debugPrint("setCustomEQ:\(err)");
+ }
+ }
+ func resetSlider(_ eqs:[NSNumber]){
+ for i in 0..<eqs.count {
+ list[i].value = eqs[i].intValue
+ }
+ }
+}
+
+private class EqSlider: BaseView {
+ let slider = UISlider()
+ let titleLabel = UILabel()
+ let valueLabel = UILabel()
+ var valueChange:((_ int:Int,_ value:Int)->Void)?
+
+ var index:Int = 0
+ var value:Int = 0{
+ didSet{
+ slider.value = Float(value)
+ valueLabel.text = "\(value)"
+ }
+ }
+
+ override func setupViews() {
+// backgroundColor = .green
+ slider.do { v in
+// v.backgroundColor = .red
+ v.minimumValue = -12
+ v.maximumValue = 12
+ v.value = 0
+ v.minimumTrackTintColor = .hexString("#0092E1")
+ v.setThumbImage(UIImage(named: "slider_icon"), for: .normal)
+ v.addTarget(self, action: #selector(sliderChanged(_:)), for: .valueChanged) // continuous changes
+
+ }
+ titleLabel.do { v in
+ v.textColor = .hexString("#999999")
+ v.textAlignment = .center
+ v.font = .regular(12)
+ v.transform = CGAffineTransform(rotationAngle: CGFloat.pi / 2)
+ }
+ valueLabel.do { v in
+ v.text = "0"
+ v.textColor = .hexString("#999999")
+ v.textAlignment = .center
+ v.font = .regular(12)
+ v.transform = CGAffineTransform(rotationAngle: CGFloat.pi / 2)
+ }
+
+ addSubviews([titleLabel,slider,valueLabel])
+ }
+
+ override func setupLayout() {
+ slider.snp.makeConstraints { make in
+ make.width.equalTo(200)
+ make.height.equalTo(30)
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(40)
+ }
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview()
+ make.width.equalTo(50)
+ }
+ valueLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(10)
+ make.width.equalTo(50)
+ }
+ }
+ @objc func sliderChanged(_ slider:UISlider){
+ let value = "\(Int(slider.value))"
+ Logger.debug(slider.value)
+ if let text = valueLabel.text, text != value {
+ valueLabel.text = value
+ valueChange?(index,Int(slider.value))
+ }
+ }
+}
+
+
+
+
--- /dev/null
+//
+// File.swift
+// ShenYin
+//
+// Created by liangshi on 2025/9/9.
+//
+
+
+
--- /dev/null
+////
+//// FindVC.swift
+//// ShenYin
+////
+//// Created by liangshi on 2025/9/9.
+////
+//
+
+import UIKit
+import JoyGemAI
+import DGActivityIndicatorView
+
+class FindVC:BaseVC{
+ private let titleLabel = UILabel()
+ private let desLabel = UILabel()
+ private let leftRadar = RadarView()
+ private let rightRadar = RadarView()
+ private let leftBtn = ButtonItem()
+ private let rightBtn = ButtonItem()
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ }
+
+ override func setupViews() {
+ self.navBar.title = "查找耳机"
+ navBar.backgroundColor = .white
+ view.backgroundColor = .color(.bgColor)
+ view.addSubviews([titleLabel,desLabel,leftRadar,rightRadar,leftBtn,rightBtn])
+
+ leftRadar.do { v in
+ v.start = false
+ v.value = "L"
+ }
+ rightRadar.do { v in
+ v.start = false
+ v.value = "R"
+ }
+ titleLabel.do { v in
+ v.text = "Deep Gen2 Max"
+ v.font = .regular(20)
+ v.textColor = .hexString("#121212")
+
+ }
+ desLabel.do { v in
+ v.text = "耳机在附近,可通过响铃进行查找。"
+ v.font = .regular(14)
+ v.textColor = .hexString("#666666")
+
+ }
+ leftBtn.do { v in
+ v.titleLabel.text = "左耳机响铃"
+ v.valueLabel.text = "L"
+ v.selected = false
+ v.yc.addTap(target: self, action: #selector(leftAction))
+ }
+ rightBtn.do { v in
+ v.titleLabel.text = "右耳机响铃"
+ v.valueLabel.text = "R"
+ v.selected = false
+ v.yc.addTap(target: self, action: #selector(rightAction))
+ }
+ }
+ override func setupLayout() {
+ titleLabel.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(184)
+ make.centerX.equalToSuperview()
+ }
+ desLabel.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(147)
+ make.centerX.equalToSuperview()
+ }
+ leftRadar.snp.makeConstraints { make in
+ make.centerY.equalToSuperview().offset(-80)
+ make.left.equalToSuperview().inset(60)
+ make.size.equalTo(100)
+ }
+ rightRadar.snp.makeConstraints { make in
+ make.centerY.equalTo(leftRadar)
+ make.right.equalToSuperview().inset(60)
+ make.size.equalTo(100)
+ }
+ leftBtn.snp.makeConstraints { make in
+ make.width.equalTo(160)
+ make.height.equalTo(46)
+ make.bottom.equalToSuperview().inset(81)
+ make.left.equalToSuperview().inset(18)
+ }
+ rightBtn.snp.makeConstraints { make in
+ make.width.equalTo(160)
+ make.height.equalTo(46)
+ make.bottom.equalToSuperview().inset(81)
+ make.right.equalToSuperview().inset(18)
+ }
+ }
+ override func setupData() {
+
+ }
+ @objc func leftAction(){
+ leftBtn.selected = !leftBtn.selected
+ if leftBtn.selected {
+ CustomAlert.showWith(title: "音量警告", messgage: "为保护听力,请勿在佩戴耳机时使用此功能。", cancel: "取消", cancelCallback: {[weak self] in
+ self?.leftBtn.selected = false
+ } ,okCallback: { [weak self] in
+ self?.leftRadar.start = true
+ self?.findAction()
+ })
+ }
+ else{
+ leftRadar.start = false
+ findAction()
+ }
+ }
+ @objc func rightAction(){
+ rightBtn.selected = !rightBtn.selected
+ if rightBtn.selected {
+ CustomAlert.showWith(title: "音量警告", messgage: "为保护听力,请勿在佩戴耳机时使用此功能。", cancel: "取消", cancelCallback: {[weak self] in
+ self?.rightBtn.selected = false
+ } ,okCallback: { [weak self] in
+ self?.rightRadar.start = true
+ self?.findAction()
+ })
+ }
+ else{
+ rightRadar.start = false
+ findAction()
+ }
+ }
+ func findAction(){
+ var mode:JoyGemFindHeadphoneMode = .cancel
+ if leftRadar.start && rightRadar.start{
+ mode = .all
+ }
+ else if leftRadar.start{
+ mode = .left
+ }
+ else if rightRadar.start{
+ mode = .right
+ }
+
+ JoyGemAIManager.shared().device.findHeadphone(mode) { err in
+ Logger.debug("findHeadphone:\(err)");
+ }
+ }
+}
+
+fileprivate class ButtonItem: BaseView {
+ let valueLabel = UILabel()
+ let titleLabel = UILabel()
+ var selected:Bool = false{
+ didSet{
+ if selected{
+ backgroundColor = .hexString("#0092E1")
+ titleLabel.textColor = .white
+ valueLabel.backgroundColor = .white
+ valueLabel.textColor = backgroundColor
+ }
+ else{
+ backgroundColor = .white
+ titleLabel.textColor = .hexString("#121212")
+ valueLabel.backgroundColor = .hexString("#0092E1")
+ valueLabel.textColor = .white
+ }
+ }
+ }
+
+ override func setupViews() {
+ addSubviews([titleLabel,valueLabel])
+ yc.setCornerRadius(12)
+ titleLabel.do { v in
+ v.font = .regular(14)
+ }
+ valueLabel.do { v in
+ v.font = .regular(14)
+ v.yc.setCornerRadius(9)
+ v.textAlignment = .center
+ }
+ }
+
+ override func setupLayout() {
+ titleLabel.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(14)
+ make.centerY.equalToSuperview()
+ }
+ valueLabel.snp.makeConstraints { make in
+ make.size.equalTo(18)
+ make.right.equalToSuperview().inset(14)
+ make.centerY.equalToSuperview()
+ }
+ }
+}
+
+fileprivate class RadarView: BaseView {
+ private let rippleView = DGActivityIndicatorView(type: .triplePulse,tintColor: UIColor.hexString("#0092E1"),size: 100)!
+ private var valueLabel = UILabel()
+ override func setupViews() {
+ yc.setCornerRadius(50)
+ addSubviews([rippleView,valueLabel])
+
+ valueLabel.do { v in
+ v.font = .regular(18)
+ v.yc.setCornerRadius(15)
+ v.textAlignment = .center
+ v.backgroundColor = UIColor.hexString("#0092E1")
+ v.textColor = .white
+ }
+ }
+ override func setupLayout() {
+ valueLabel.snp.makeConstraints { make in
+ make.width.equalTo(30)
+ make.height.equalTo(30)
+ make.center.equalToSuperview()
+ }
+ rippleView.snp.makeConstraints { make in
+ make.size.equalTo(100)
+ make.center.equalToSuperview()
+ }
+ }
+ var value:String = ""{
+ didSet{
+ valueLabel.text = value
+ }
+ }
+ var start:Bool = false{
+ didSet{
+ if start {
+ rippleView.startAnimating()
+ backgroundColor = .clear
+ }
+ else{
+ rippleView.stopAnimating()
+ backgroundColor = UIColor.hexString("#0092E1").withAlphaComponent(0.1)
+ }
+ }
+ }
+}
// Created by liangshi on 2025/8/12.
//
+import UIKit
+import JoyGemAI
+
enum ModeEffectsType:Int{
case normal
case fashion
return "mode_custom"
}
}
+ var value:JoyGemEQMode{
+ switch self {
+ case .normal:
+ return .normal
+ case .fashion:
+ return .pop
+ case .classic:
+ return .classic
+ case .rock:
+ return .rock
+ case .jazz:
+ return .jazz
+ case .custom:
+ return .custom
+ }
+ }
+
+ static var all:[ModeEffectsType]{
+ return [.normal,.fashion,.classic,.rock,.jazz,.custom]
+ }
}
class ModeEffectsView: BaseView {
let titleLabel = UILabel()
- var list:[ModeEffectsType] = [.normal,.fashion,.classic,.rock,.jazz,.custom]
+ var list:[ModeEffectsType] = ModeEffectsType.all
var itemViews = [ItemView]()
+ var selectedMode:((_ mode:JoyGemEQMode)->Void)?
+
+ var mode:JoyGemEQMode = .normal{
+ didSet{
+ for item in itemViews {
+ if mode == item.type.value {
+ item.isSelected = true
+ }
+ else{
+ item.isSelected = false
+ }
+ }
+ }
+ }
+
override func setupViews() {
backgroundColor = .white
-
yc.setCornerRadius(12)
addSubviews([titleLabel])
var y = 47.0
for (index, value) in list.enumerated() {
let view = ItemView()
+ view.yc.addTap(target: self, action: #selector(tapAction))
addSubview(view)
+ itemViews.append(view)
view.type = value
x = Double(index%2)*w + Double(index%2 + 1)*13
make.left.equalToSuperview().inset(x)
make.top.equalToSuperview().inset(y)
if index == list.count - 1 {
- make.bottom.equalToSuperview()
+ make.bottom.equalToSuperview().inset(14)
}
}
}
@objc func tapAction(_ tap:UITapGestureRecognizer){
let view = tap.view as! ItemView
-
+ for item in itemViews {
+ if view == item {
+ view.isSelected = true
+ }
+ else{
+ item.isSelected = false
+ }
+ }
+ selectedMode?(view.type.value)
}
class ItemView: BaseView {
let icon = UIImageView()
let titleLabel = UILabel()
+ let selectedIcon = UIImageView()
var type = ModeEffectsType.fashion{
didSet{
titleLabel.text = type.title
}
}
+ var isSelected:Bool = false{
+ didSet{
+ selectedIcon.isHidden = !isSelected
+ }
+ }
override func setupViews() {
- addSubviews([icon,titleLabel])
+ addSubviews([icon,titleLabel,selectedIcon])
icon.do { v in
v.yc.setCornerRadius(8)
}
v.textColor = .white
v.font = .regular(14)
}
+ selectedIcon.image = UIImage(named: "mode_selected")
+ selectedIcon.isHidden = true
}
override func setupLayout() {
titleLabel.snp.makeConstraints { make in
make.center.equalToSuperview()
}
+ selectedIcon.snp.makeConstraints { make in
+ make.size.equalTo(20)
+ make.right.top.equalToSuperview().inset(6)
+ }
}
}
-enum ModeFindType:Int{
- case left
- case right
-
- var title:String{
- switch self {
- case .left:
- return "L"
- case .right:
- return "R"
- }
- }
-}
-
class ModeFindView: BaseView {
+ let icon = UIImageView()
let titleLabel = UILabel()
- var list:[ModeFindType] = [.left,.right]
- var itemViews = [ItemView]()
-
+
override func setupViews() {
backgroundColor = .white
-
yc.setCornerRadius(12)
+ addSubviews([icon,titleLabel])
- addSubviews([titleLabel])
- titleLabel.do { (v) in
- v.textColor = .rgb(0x121212)
- v.font = .bold(14)
+ icon.image = UIImage(named: "find_icon")
+ titleLabel.do { v in
v.text = "查找耳机"
- }
-
- let w = 66.0
- let h = 66
- let y = 38
- for (index, value) in list.enumerated() {
- let view = ItemView()
- view.yc.setCornerRadius(w/2)
- addSubview(view)
- itemViews.append(view)
- view.yc.addTap(target: self, action: #selector(tapAction))
+ v.font = .bold(16)
+ v.textColor = .hexString("#121212")
- view.type = value
- view.snp.makeConstraints { make in
- make.width.equalTo(w)
- make.height.equalTo(h)
- make.top.equalToSuperview().inset(y)
- if index == list.count - 1 {
- make.right.equalToSuperview().inset(68)
- }
- else if( index == 0){
- view.isSelected = true
- make.left.equalToSuperview().inset(68)
- }
- else{
- make.centerX.equalToSuperview()
- }
- }
}
}
-
override func setupLayout() {
- titleLabel.snp.makeConstraints { make in
- make.top.left.equalToSuperview().inset(14)
+ icon.snp.makeConstraints { make in
+ make.size.equalTo(26)
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
}
- }
-
- @objc func tapAction(_ tap:UITapGestureRecognizer){
- let view = tap.view as! ItemView
- }
-
- class ItemView: BaseView {
- let icon = UIImageView()
- let titleLabel = UILabel()
- var type = ModeFindType.left{
- didSet{
- titleLabel.text = type.title
- }
- }
- var isSelected:Bool = false{
- didSet{
- if isSelected {
- titleLabel.textColor = .color(.theme)
- }
- else{
- titleLabel.textColor = .rgb(0x666666)
- }
- }
- }
-
- override func setupViews() {
- addSubviews([icon,titleLabel])
- icon.do { v in
- v.backgroundColor = .gray
- v.yc.setCornerRadius(8)
- }
- titleLabel.do { (v) in
- v.textColor = .color(.theme)
- v.font = .regular(12)
- }
- }
-
- override func setupLayout() {
- icon.snp.makeConstraints { make in
- make.edges.equalToSuperview()
- }
- titleLabel.snp.makeConstraints { make in
- make.center.equalToSuperview()
- }
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalTo(icon.snp.right).offset(10)
}
}
-
}
// Created by liangshi on 2025/8/5.
//
import UIKit
-
+import JoyGemAI
class ModeVC:BaseVC{
let bgView = UIScrollView()
let headerView = CurrentDeviceView()
override func setupViews() {
self.navBar.title = "模式"
navBar.backgroundColor = .white
- view.backgroundColor = .color(.bgColor)
- navBar.rightView.setImage(UIImage(named: "add_icon"), for: .normal)
+// navBar.rightView.setImage(UIImage(named: "add_icon"), for: .normal)
+
view.addSubview(bgView)
bgView.addSubviews([headerView,controlView,effectsView,findView])
+
+// bgView.backgroundColor = .red
+ effectsView.do { v in
+ v.selectedMode = {[weak self] mode in
+ self?.selectedModeAction(mode)
+ }
+ }
+ findView.yc.addTap(target: self, action: #selector(findAction))
}
override func setupLayout() {
bgView.snp.makeConstraints { make in
make.top.equalTo(kNavBtm)
- make.left.right.bottom.equalToSuperview()
+ make.left.right.equalToSuperview()
+ make.height.equalTo(kScreenHei - kNavBtm - kTabbarHei)
}
headerView.snp.makeConstraints { make in
make.top.equalToSuperview()
}
effectsView.snp.makeConstraints { make in
make.top.equalTo(controlView.snp.bottom).offset(10)
- make.centerX.equalToSuperview()
- make.width.equalTo(controlView)
+ make.left.width.equalTo(controlView)
+ make.height.equalTo(325)
}
findView.snp.makeConstraints { make in
make.top.equalTo(effectsView.snp.bottom).offset(10)
- make.centerX.equalToSuperview()
- make.width.equalTo(effectsView)
- make.height.equalTo(115)
+ make.left.width.equalTo(effectsView)
+ make.height.equalTo(62)
make.bottom.equalToSuperview().inset(20)
}
}
+ override func setupData() {
+ JoyGemAIManager.shared().device.getEQMode {[weak self] mode in
+ guard let self = self else{return}
+ effectsView.mode = mode
+ } error: { err in
+ Logger.debug("getEQMode:\(err)");
+ }
+ }
override func navRightViewTapped() {
}
}
+extension ModeVC{
+ func selectedModeAction(_ mode:JoyGemEQMode){
+ JoyGemAIManager.shared().device.setEQMode(mode) { err in
+ Logger.debug("setEQMode:\(err)");
+ }
+ if mode == .custom {
+ App.shared.goToPage(CustomEqVC())
+ }
+ }
+ @objc func findAction(){
+ App.shared.goToPage(FindVC())
+ }
+}
+
var model:CBPeripheral!{
didSet{
titleLabel.text = model.name
- titleLabel.text = titleLabel.text! + "\n" + model.identifier.uuidString
+// titleLabel.text = titleLabel.text! + "\n" + model.identifier.uuidString
titleLabel.adjustsFontSizeToFitWidth = true
}
}
--- /dev/null
+//
+// GlobalConfig.swift
+// ShenYin
+//
+// Created by liangshi on 2025/8/27.
+//
+
+import Foundation
+import JoyGemAI
+
+enum AiSupportLanguage{
+ case chinse
+ case english
+ case japanese
+ case korean
+ case french
+ case spanish
+ case portuguese
+ case indonesian
+ case russian
+ case malay
+
+ /// 现场录音,通话录音,同声传译
+ static var record:[AiSupportLanguage]{
+ return [.chinse,.english,.japanese,.korean]
+ }
+ static var chinse2english:[AiSupportLanguage]{
+ return [.chinse,.english]
+ }
+ static var dialog:[AiSupportLanguage]{
+ return [.chinse,.english,.japanese]
+ }
+ static var translate:[AiSupportLanguage]{
+ return [.chinse,.english,.japanese,.korean,.french,.spanish,.portuguese,.indonesian,.russian,.malay]
+ }
+ var title:String{
+ switch self {
+ case .chinse:
+ return "中文"
+ case .english:
+ return "英文"
+ case .japanese:
+ return "日文"
+ case .korean:
+ return "韩文"
+ case .french:
+ return "法语"
+ case .spanish:
+ return "西班牙文"
+ case .portuguese:
+ return "葡萄牙文"
+ case .indonesian:
+ return "印度尼西亚文"
+ case .russian:
+ return "俄文"
+ case .malay:
+ return "马来文"
+ }
+ }
+ var value:String{
+ switch self {
+ case .chinse:
+ return kJoyGemAILocalizationZH
+ case .english:
+ return kJoyGemAILocalizationEN
+ case .japanese:
+ return kJoyGemAILocalizationJA
+ case .korean:
+ return kJoyGemAILocalizationKO
+ case .french:
+ return kJoyGemAILocalizationFR
+ case .spanish:
+ return kJoyGemAILocalizationES
+ case .portuguese:
+ return kJoyGemAILocalizationPT
+ case .indonesian:
+ return kJoyGemAILocalizationID
+ case .russian:
+ return kJoyGemAILocalizationRU
+ case .malay:
+ return kJoyGemAILocalizationMS
+ }
+ }
+
+}
+//现场录音 中,英,日,韩
+//通话录音 中,英,日,韩
+//双耳互译 中英
+//同声传译 中,英,日,韩
+//面对面翻译 中,英,日
+//文本翻译 中、英、日、韩、法、西班牙、葡萄牙、印度尼西亚、俄文、马来文
+
--- /dev/null
+//
+// CustomAlert.swift
+// ShenYin
+//
+// Created by liangshi on 2025/9/9.
+//
+
+
+class CustomAlert {
+
+ static func showWith(title:String,messgage:String,cancel:String = "取消",ok:String = "确定",cancelCallback: (()->Void)?,okCallback: (()->Void)?){
+ let vc = UIAlertController(title: "音量警告", message: "为保护听力,请勿在佩戴耳机时使用此功能。", preferredStyle: .alert)
+ let action0 = UIAlertAction(title: "取消", style: .cancel) { action in
+ cancelCallback?()
+ }
+ let action1 = UIAlertAction(title: "播放", style: .default) { action in
+ okCallback?()
+ }
+ vc.addAction(action0)
+ vc.addAction(action1)
+ App.shared.topVC()?.present(vc, animated: true)
+ }
+
+}
+++ /dev/null
-//
-// Untitled.swift
-// ShenYin
-//
-// Created by liangshi on 2025/8/14.
-//
-
-import UIKit
-class RecordTranslateTipsView: BasePresentView {
- let titleLabel = UILabel()
- let btn = UIButton(type: .custom)
- let tipsIcon = UIImageView()
- let desLabel1 = UILabel()
- let desLabel2 = UILabel()
- let actionbtn = UIButton(type: .custom)
- var didSelected: ((Int,String)->Void)?
-
- init() {
- let h = 595.0
- super.init(contentHeight:h)
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
- override func setupSubView() {
- super.setupSubView()
- contentView.addSubviews([titleLabel,btn,tipsIcon,desLabel1,desLabel2,actionbtn])
- }
- override func setupLayout() {
- super.setupLayout()
- titleLabel.snp.makeConstraints { (m) in
- m.top.equalToSuperview()
- m.left.right.equalToSuperview().inset(60)
- m.height.equalTo(50)
- }
- btn.snp.makeConstraints { (m) in
- m.centerY.equalTo(titleLabel)
- m.right.equalToSuperview()
- m.size.equalTo(60)
- }
- tipsIcon.snp.makeConstraints { make in
- make.left.right.equalTo(18)
- make.top.equalToSuperview().inset(64)
- make.height.equalTo(234)
- }
- titleLabel.snp.makeConstraints { (m) in
- m.top.equalToSuperview()
- m.left.right.equalToSuperview().inset(60)
- m.height.equalTo(50)
- }
- }
-
- override func setupStyle() {
- super.setupStyle()
- contentView.backgroundColor = .white
- titleLabel.do { (v) in
- v.textColor = .rgb(0x333333)
- v.font = .semiBold(16)
- v.textAlignment = .center
- v.text = "同传听译模式使用介绍"
- }
- btn.do { v in
- v.setImage(UIImage(named: "close_icon"), for: .normal)
- v.addTarget(self, action: #selector(closeAction), for: .touchUpInside)
- }
- tipsIcon.do { v in
- v.image = UIImage(named: "")
- }
-
- }
- @objc func closeAction(){
- hide()
- }
-}
let leftLabel = LanguageItem()
let rightLabel = LanguageItem()
let switcIcon = UIImageView()
+ var valueChange:(()->Void)?
+
+ var currentLanguage:AiSupportLanguage{
+ if isRight {
+ return rightLabel.language
+ }
+ return leftLabel.language
+ }
var isRight:Bool{
if rightLabel.isSelected{
switcIcon.do { v in
v.image = UIImage(named: "language_switch_gray")
v.contentMode = .center
+ v.yc.addTap(target: self, action: #selector(swictAction))
}
leftLabel.do { (v) in
v.yc.addTap(target: self, action: #selector(leftAction))
v.isSelected = true
+ v.language = .chinse
}
rightLabel.do { (v) in
v.yc.addTap(target: self, action: #selector(rightAction))
v.isSelected = false
+ v.language = .english
}
}
make.centerY.equalToSuperview()
}
}
+ @objc func swictAction(){
+ let lan1 = leftLabel.language
+ let lan2 = rightLabel.language
+ rightLabel.language = lan1
+ leftLabel.language = lan2
+ valueChange?()
+ }
@objc func leftAction(){
leftLabel.isSelected = true
rightLabel.isSelected = false
+ valueChange?()
}
@objc func rightAction(){
leftLabel.isSelected = false
rightLabel.isSelected = true
+ valueChange?()
}
class LanguageItem: BaseView {
- let label = UILabel()
+ private let label = UILabel()
+ var language:AiSupportLanguage = .chinse{
+ didSet{
+ label.text = language.title
+ }
+ }
var isSelected:Bool = false{
didSet{
if isSelected {
addSubviews([label])
label.do { (v) in
v.font = .medium(14)
- v.text = "中文"
v.textAlignment = .center
v.backgroundColor = .white
v.textColor = .hexString("#0092E1")
import UIKit
class LanguagePickerView: BasePresentView {
- private let titleLabel = LanguagePickerTitle()
+ private let segView = LanguagePickerTitle()
private let btn = UIButton(type: .custom)
private let tableView = UITableView(frame: .zero, style: .plain)
- var list:[String] = GlobalConfig.tranlateLanguages
+ var list:[AiSupportLanguage] = []
var selectedIndex = 0{
didSet{
tableView.reloadData()
}
}
- var didSelected: ((Int,String)->Void)?
+
+
+ var didSelected: ((Int,AiSupportLanguage)->Void)?
private var title:String = "请选择语言"
- init(isLeft:Bool = true) {
+ init(languages:[AiSupportLanguage],isLeft:Bool,left:AiSupportLanguage,right:AiSupportLanguage) {
+ list = languages
+ segView.leftLabel.language = left
+ segView.rightLabel.language = right
if isLeft {
- titleLabel.leftAction()
+ segView.leftAction()
}
else{
- titleLabel.rightAction()
+ segView.rightAction()
}
- let h = CGFloat(50 + list.count*52) + kSafeBtm
+ let h = CGFloat(85 + list.count*52) + kSafeBtm
super.init(contentHeight:h)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
-// LanguagePickerView(title: "", list: )
override func setupSubView() {
super.setupSubView()
- contentView.addSubviews([titleLabel,btn,tableView])
+ contentView.addSubviews([segView,btn,tableView])
}
override func setupLayout() {
super.setupLayout()
- titleLabel.snp.makeConstraints { (m) in
+ segView.snp.makeConstraints { (m) in
m.top.equalToSuperview()
m.left.right.equalToSuperview()
}
btn.snp.makeConstraints { (m) in
- m.centerY.equalTo(titleLabel)
+ m.centerY.equalTo(segView)
m.right.equalToSuperview()
m.size.equalTo(60)
}
tableView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
- make.top.equalTo(titleLabel.snp.bottom)
+ make.top.equalTo(segView.snp.bottom)
make.bottom.equalToSuperview()
}
}
super.setupStyle()
contentView.backgroundColor = .white
+ segView.do { v in
+ v.valueChange = { [weak self] in
+ self?.selectedBtnChange()
+ }
+ }
btn.do { v in
v.isHidden = true
v.setImage(UIImage(named: "close_icon"), for: .normal)
@objc func closeAction(){
hide()
}
+ func selectedBtnChange(){
+ let language = segView.currentLanguage
+ selectedIndex = list.firstIndex(where: {$0 == language})!
+ tableView.reloadData()
+ }
}
extension LanguagePickerView:UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = LanguagePickerView.SelectCell.cell(withTableView: tableView, indexPath: indexPath)
- cell.titleLabel.text = list[indexPath.row]
+ cell.titleLabel.text = list[indexPath.row].title
cell.selectedIcon.isHidden = selectedIndex != indexPath.row
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedIndex = indexPath.row
tableView.reloadData()
- didSelected?(titleLabel.isRight ? 1:0 ,list[selectedIndex])
+ didSelected?(segView.isRight ? 1:0 ,list[selectedIndex])
hide()
}
}
let leftLabel = LanguageItem()
let rightLabel = LanguageItem()
let switcIcon = UIImageView()
-
override func setupViews() {
addSubviews([bottonView])
v.yc.addTap(target: self, action: #selector(switchAction))
}
leftLabel.do { (v) in
- v.label.text = "中文"
+ v.language = AiSupportLanguage.chinse
v.yc.addTap(target: self, action: #selector(leftAction))
}
rightLabel.do { (v) in
- v.label.text = "英文"
+ v.language = AiSupportLanguage.english
v.yc.addTap(target: self, action: #selector(rightAction))
}
}
}
}
@objc func switchAction(){
- let text1 = leftLabel.label.text
- let text2 = rightLabel.label.text
- leftLabel.label.text = text2
- rightLabel.label.text = text1
+ let text1 = leftLabel.language
+ let text2 = rightLabel.language
+ leftLabel.language = text2
+ rightLabel.language = text1
}
@objc func leftAction(){
- let v = LanguagePickerView(isLeft: true)
- v.selectedIndex = v.list.firstIndex(where: {$0 == leftLabel.label.text}) ?? 0
+ let v = LanguagePickerView(languages: AiSupportLanguage.translate,isLeft: true,left: leftLabel.language,right: rightLabel.language)
+ v.selectedIndex = v.list.firstIndex(where: {$0.title == leftLabel.language.title}) ?? 0
v.show()
v.didSelected = {[weak self] (index,value) in
guard let self = self else { return }
if index == 0 {
- leftLabel.label.text = value
+ leftLabel.language = value
}
else{
- rightLabel.label.text = value
+ rightLabel.language = value
}
}
}
@objc func rightAction(){
- let v = LanguagePickerView(isLeft: false)
- v.selectedIndex = v.list.firstIndex(where: {$0 == rightLabel.label.text}) ?? 0
+ let v = LanguagePickerView(languages: AiSupportLanguage.translate,isLeft: false,left: leftLabel.language,right: rightLabel.language)
+ v.selectedIndex = v.list.firstIndex(where: {$0.title == rightLabel.language.title}) ?? 0
v.show()
v.didSelected = {[weak self] (index,value) in
guard let self = self else { return }
if index == 0 {
- leftLabel.label.text = value
+ leftLabel.language = value
}
else{
- rightLabel.label.text = value
+ rightLabel.language = value
}
}
}
class LanguageItem: BaseView {
- let label = UILabel()
+ private let label = UILabel()
+ var language:AiSupportLanguage = AiSupportLanguage.chinse{
+ didSet{
+ label.text = language.title
+ }
+ }
override func setupViews() {
// backgroundColor = .yellow
}
textFiled.do { v in
- v.text = "7月17日 9点23分"
+ v.text = Date().format(.full2)
v.font = .bold(16)
v.textColor = .hexString("#121212")
}
--- /dev/null
+//
+// Untitled.swift
+// ShenYin
+//
+// Created by liangshi on 2025/8/14.
+//
+
+import UIKit
+
+
+enum RecordTipsType:Int{
+ case dialog
+ case chinese2english
+ case tongchuan
+
+ var title:String{
+ switch self {
+ case .dialog:
+ return "对话模式使用介绍"
+ case .chinese2english:
+ return "中英互译模式使用介绍"
+ case .tongchuan:
+ return "同传听译模式使用介绍"
+ }
+ }
+ var icon:String{
+ switch self {
+ case .dialog:
+ return "tips_dialog"
+ case .chinese2english:
+ return "tips_chinese2english"
+ case .tongchuan:
+ return "tips_tongchuan"
+ }
+ }
+ var des1:String{
+ switch self {
+ case .dialog:
+ return "靠近手机讲母语,手机外放译文"
+ case .chinese2english:
+ return "两人各佩戴一只耳机,选择源语言语种, 双方耳机中播放目标语言"
+ case .tongchuan:
+ return "手机靠近音源收音,佩戴耳机收听译文"
+ }
+ }
+ var des2:String{
+ switch self {
+ case .dialog:
+ return "- 情景示例 -\n张张靠近手机讲中文,手机外放英语"
+ case .chinese2english:
+ return "- 情景示例 -\n张张戴一只耳机讲中文,双方耳机播放英文翻译 Lucy切换为英语发言后,双方耳机中播报中文翻译"
+ case .tongchuan:
+ return "- 情景示例 -\nLisa对着手机讲英语,小徐耳机中播放中文"
+ }
+ }
+}
+
+
+class RecordTipsView: BasePresentView {
+ let titleLabel = UILabel()
+ let btn = UIButton(type: .custom)
+ let tipsIcon = UIImageView()
+ let desLabel1 = UILabel()
+ let desLabel2 = UILabel()
+ let actionbtn = UIButton(type: .custom)
+ var didSelected: ((Int,String)->Void)?
+ var tipsType:RecordTipsType = .dialog
+
+ init(type:RecordTipsType) {
+ tipsType = type
+ let h = 595.0
+ super.init(contentHeight:h)
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ override func setupSubView() {
+ super.setupSubView()
+ contentView.addSubviews([titleLabel,btn,tipsIcon,desLabel1,desLabel2,actionbtn])
+ }
+ override func setupLayout() {
+ super.setupLayout()
+ titleLabel.snp.makeConstraints { (m) in
+ m.top.equalToSuperview()
+ m.left.right.equalToSuperview().inset(36)
+ m.height.equalTo(60)
+ }
+ btn.snp.makeConstraints { (m) in
+ m.centerY.equalTo(titleLabel)
+ m.right.equalToSuperview()
+ m.size.equalTo(60)
+ }
+ tipsIcon.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalToSuperview().inset(64)
+ make.height.equalTo(234)
+ }
+ desLabel1.snp.makeConstraints { (m) in
+ m.top.equalTo(tipsIcon.snp.bottom).offset(20)
+ m.left.right.equalToSuperview().inset(40)
+ }
+ desLabel2.snp.makeConstraints { (m) in
+ m.top.equalTo(desLabel1.snp.bottom).offset(30)
+ m.left.right.equalToSuperview().inset(30)
+ }
+ actionbtn.snp.makeConstraints { (m) in
+ m.top.equalTo(desLabel2.snp.bottom).offset(40)
+ m.left.right.equalToSuperview().inset(52)
+ m.height.equalTo(46)
+ }
+
+ }
+
+ override func setupStyle() {
+ super.setupStyle()
+ contentView.backgroundColor = .white
+ titleLabel.do { (v) in
+ v.textColor = .rgb(0x121212)
+ v.font = .semiBold(16)
+ v.textAlignment = .center
+ v.text = tipsType.title
+ }
+ btn.do { v in
+ v.setImage(UIImage(named: "close_icon"), for: .normal)
+ v.addTarget(self, action: #selector(closeAction), for: .touchUpInside)
+ }
+ tipsIcon.do { v in
+ v.image = UIImage(named: tipsType.icon)
+ v.backgroundColor = .lightGray
+ v.yc.setCornerRadius(20)
+ }
+ desLabel1.do { v in
+ let text = tipsType.des1
+ let attributedString = NSMutableAttributedString(string: text)
+ let paragraphStyle = NSMutableParagraphStyle()
+ paragraphStyle.lineSpacing = 10
+ attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: text.count))
+ v.attributedText = attributedString
+
+ v.textColor = .rgb(0x121212)
+ v.font = .semiBold(16)
+ v.textAlignment = .center
+ v.numberOfLines = 0
+ }
+ desLabel2.do { v in
+ let text = tipsType.des2
+ let attributedString = NSMutableAttributedString(string: text)
+ let paragraphStyle = NSMutableParagraphStyle()
+ paragraphStyle.lineSpacing = 10
+ attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: text.count))
+ v.attributedText = attributedString
+ v.textColor = .rgb(0x919191)
+ v.font = .semiBold(14)
+ v.textAlignment = .center
+ v.numberOfLines = 0
+ }
+ actionbtn.do { v in
+ v.backgroundColor = .hexString("#0092E1")
+ v.setTitle("开始体验", for: .normal)
+ v.titleLabel?.font = .regular(14)
+ v.yc.setCornerRadius(12)
+ v.setTitleColor(.white, for: .normal)
+ v.addTarget(self, action: #selector(btnAction), for: .touchUpInside)
+ }
+ }
+ @objc func closeAction(){
+ hide()
+ }
+ @objc func btnAction(){
+
+ }
+}
pod 'SocketRocket'#socket,AI用到
pod 'DGActivityIndicatorView'#扫描雷达
+ pod 'MultiSlider'
# pod 'NVActivityIndicatorView', '~> 5.1.1' # 最新稳定版
# pod 'EZAudio', '~> 1.1.0'
end
}
@objc func scan() {
+// cbInfomations.removeAll()
+// tableView.reloadData()
+// cbManager.scanForPeripherals(withServices: [CBUUID(string: kJoyGemAIServiceUUID)],options: [CBCentralManagerScanOptionAllowDuplicatesKey : false])
+// //cbManager.scanForPeripherals(withServices: [],options: [CBCentralManagerScanOptionAllowDuplicatesKey : false])
+
+
+ print(" === \(kJoyGemAIServiceUUID)")
cbInfomations.removeAll()
tableView.reloadData()
cbManager.scanForPeripherals(withServices: [CBUUID(string: kJoyGemAIServiceUUID)],options: [CBCentralManagerScanOptionAllowDuplicatesKey : false])
- //cbManager.scanForPeripherals(withServices: [],options: [CBCentralManagerScanOptionAllowDuplicatesKey : false])
+
+
+ let devices = cbManager.retrieveConnectedPeripherals(withServices: [CBUUID(string: kJoyGemAIServiceUUID)])
+ for item in devices {
+ print(item)
+ // DB209A55-DD0E-5031-29FA-40D734C34971
+ // "edr:21140DE4C3D9"
+ // "ble:21140D2CC682"
+ let vc = PeripheralViewController()
+ vc.cbManager = cbManager
+ vc.currentPeripheral = item
+ self.navigationController?.pushViewController(vc, animated: true)
+ break
+ }
}
}