Channel/PLAYBOY/PLAYBOY.storyboard,
Channel/PLAYBOY/PLAYBOY.xcassets,
Channel/recording.gif,
+ UI/Home/Dialog/DialogRecordBar.swift,
+ UI/Home/FieldRecording/Chinese2EnglishRecordBar.swift,
+ UI/Home/FieldRecording/FieldRecordBar.swift,
);
target = 3F1301D42F750E7400B9B4F5 /* PaXa */;
};
Channel/DeepChords/DeepChords.plist,
Channel/PaXa/Config/BleScanHeaderView.swift,
Channel/PaXa/Config/CCConfig.swift,
+ Channel/PaXa/Config/Chinese2EnglishRecordBar.swift,
Channel/PaXa/Config/CustomButton.swift,
+ Channel/PaXa/Config/DialogRecordBar.swift,
+ Channel/PaXa/Config/FieldRecordBar.swift,
Channel/PaXa/PaXa.plist,
Channel/PaXa/PaXa.storyboard,
Channel/PaXa/PaXa.xcassets,
Channel/DeepChords/Sdk/JoyTcty.swift,
Channel/PaXa/Config/BleScanHeaderView.swift,
Channel/PaXa/Config/CCConfig.swift,
+ Channel/PaXa/Config/Chinese2EnglishRecordBar.swift,
Channel/PaXa/Config/CustomButton.swift,
+ Channel/PaXa/Config/DialogRecordBar.swift,
+ Channel/PaXa/Config/FieldRecordBar.swift,
Channel/PaXa/PaXa.plist,
Channel/PaXa/PaXa.storyboard,
Channel/PaXa/PaXa.xcassets,
CODE_SIGN_ENTITLEMENTS = ShenYin/Channel/PLAYBOY/PLAYBOY.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 202604081115;
+ CURRENT_PROJECT_VERSION = 202604081715;
DEVELOPMENT_TEAM = JKLJ58J33Q;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
CODE_SIGN_ENTITLEMENTS = ShenYin/Channel/PLAYBOY/PLAYBOY.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 202604081115;
+ CURRENT_PROJECT_VERSION = 202604081715;
DEVELOPMENT_TEAM = JKLJ58J33Q;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
static let preferredStatusBarStyle: UIStatusBarStyle = .darkContent
static let currentDeviceSize = CGSize(width: 168, height: 138)
+ static let popPlaySize = CGSize(width: 60, height: 60)
+ static let dialogRecordBarHeight = kNavBtm + 15
}
extension YLColor: ColorRGBProviderProtocol {
public var rgbValue: Int {
import UIKit
import AVFAudio
class JoyChinese2EnglishVC:BaseVC{
- let toolBar = RecordBar()
+ let toolBar = Chinese2EnglishRecordBar()
let tableView = UITableView(frame: CGRectZero, style: .plain)
let bg = UIImageView()
let sdk = JoyChinse2English()
}
}
}
-extension JoyChinese2EnglishVC:RecordBarDelegate{
- func recordBarLanguageChange(_ bar: RecordBar) {
+extension JoyChinese2EnglishVC:Chinese2EnglishRecordBarDelegate{
+ func recordBarLanguageChange(_ bar: Chinese2EnglishRecordBar) {
}
- func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
+ func recordBar(_ bar: Chinese2EnglishRecordBar, stateChange state: Chinese2EnglishRecordBarSate) {
if state == .start {
sdk.start()
}
make.bottom.equalTo(toolBar.snp.top)
}
splitView.snp.makeConstraints { make in
- make.top.equalToSuperview().inset(kNavBtm + 15)
+ make.top.equalToSuperview().inset(CCConfig.dialogRecordBarHeight)
make.left.equalToSuperview()
make.width.equalTo(kScreenWid)
make.bottom.equalTo(toolBar.snp.top)
}
}
- func recordBar(_ bar: DialogRecordBar, device: DialogRecordDeviceType, stateChange state: RecordBarSate) {
+ func recordBar(_ bar: DialogRecordBar, device: DialogRecordDeviceType, stateChange state: DialogRecordDeviceState) {
if device == .earphone {
if state == .start {
startEarRecord()
import UIKit
import AVFoundation
class JoyTctyVC:BaseVC{
- let toolBar = RecordBar()
+ let toolBar = Chinese2EnglishRecordBar()
let textView = PlaceHolderTextView()
let translateTextView = PlaceHolderTextView()
let sdk = JoyTcty()
}
}
-extension JoyTctyVC:RecordBarDelegate{
- func recordBarLanguageChange(_ bar:RecordBar){
+extension JoyTctyVC:Chinese2EnglishRecordBarDelegate{
+ func recordBarLanguageChange(_ bar:Chinese2EnglishRecordBar){
AiLanguageCache.save(type: .tscy_left, lan: bar.leftItem.language)
AiLanguageCache.save(type: .tscy_right, lan: bar.rightItem.language)
}
- func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
+ func recordBar(_ bar: Chinese2EnglishRecordBar, stateChange state: Chinese2EnglishRecordBarSate) {
if state == .start {
textView.text = nil
translateTextView.text = nil
static let userInfoList:[UserInfoCellType] = [.avatar,.nickName,.gender,.uid,.area]
static let preferredStatusBarStyle: UIStatusBarStyle = .lightContent
static let currentDeviceSize = CGSize(width: 168, height: 138)
+ static let popPlaySize = CGSize(width: 60, height: 60)
+ static let dialogRecordBarHeight = kNavBtm + 15
}
extension YLColor: ColorRGBProviderProtocol {
import UIKit
import AVFAudio
class PbChinese2EnglishVC:BaseVC{
- let toolBar = RecordBar()
+ let toolBar = Chinese2EnglishRecordBar()
let tableView = UITableView(frame: CGRectZero, style: .plain)
let bg = UIImageView()
let sdk = DcChinese2Enligsh()
}
}
}
-extension PbChinese2EnglishVC:RecordBarDelegate{
- func recordBarLanguageChange(_ bar: RecordBar) {
+extension PbChinese2EnglishVC:Chinese2EnglishRecordBarDelegate{
+ func recordBarLanguageChange(_ bar: Chinese2EnglishRecordBar) {
}
- func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
+ func recordBar(_ bar: Chinese2EnglishRecordBar, stateChange state: Chinese2EnglishRecordBarSate) {
if state == .start {
sdk.start()
}
make.bottom.equalTo(toolBar.snp.top)
}
splitView.snp.makeConstraints { make in
- make.top.equalToSuperview().inset(kNavBtm + 15)
+ make.top.equalToSuperview().inset(CCConfig.dialogRecordBarHeight)
make.left.equalToSuperview()
make.width.equalTo(kScreenWid)
make.bottom.equalTo(toolBar.snp.top)
}
}
- func recordBar(_ bar: DialogRecordBar, device: DialogRecordDeviceType, stateChange state: RecordBarSate) {
+ func recordBar(_ bar: DialogRecordBar, device: DialogRecordDeviceType, stateChange state: DialogRecordDeviceState) {
if device == .earphone {
if state == .start {
startEarRecord()
@available(iOS 15.0, *)
class PbSubTitleVC: BaseVC {
let languageItem = LanguageSelectItem()
- let toolBar = RecordBar()
+ let toolBar = Chinese2EnglishRecordBar()
let tableView = UITableView(frame: CGRectZero, style: .plain)
}
@available(iOS 15.0, *)
-extension PbSubTitleVC:RecordBarDelegate{
- func recordBarLanguageChange(_ bar: RecordBar) {
+extension PbSubTitleVC:Chinese2EnglishRecordBarDelegate{
+ func recordBarLanguageChange(_ bar: Chinese2EnglishRecordBar) {
sdk.stopEarRecord()
sdk.startEarRecord(from: languageItem.leftLabel.language, to: languageItem.rightLabel.language)
}
- func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
+ func recordBar(_ bar: Chinese2EnglishRecordBar, stateChange state: Chinese2EnglishRecordBarSate) {
if state == .start {
sdk.startEarRecord(from: languageItem.leftLabel.language, to: languageItem.rightLabel.language)
pipManager.start()
import UIKit
import AVFoundation
class PbTctyVC:BaseVC{
- let toolBar = RecordBar()
+ let toolBar = Chinese2EnglishRecordBar()
let textView = PlaceHolderTextView()
let translateTextView = PlaceHolderTextView()
let sdk = DcTcty()
}
}
-extension PbTctyVC:RecordBarDelegate{
- func recordBarLanguageChange(_ bar:RecordBar){
+extension PbTctyVC:Chinese2EnglishRecordBarDelegate{
+ func recordBarLanguageChange(_ bar:Chinese2EnglishRecordBar){
AiLanguageCache.save(type: .tscy_left, lan: bar.leftItem.language)
AiLanguageCache.save(type: .tscy_right, lan: bar.rightItem.language)
}
- func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) {
+ func recordBar(_ bar: Chinese2EnglishRecordBar, stateChange state: Chinese2EnglishRecordBarSate) {
if state == .start {
textView.text = nil
translateTextView.text = nil
static let preferredStatusBarStyle: UIStatusBarStyle = .darkContent
static let currentDeviceSize = CGSize(width: 168, height: 138)
+ static let popPlaySize = CGSize(width: 138, height: 45)
+ static let dialogRecordBarHeight = kNavBtm + 25
}
--- /dev/null
+//
+// RecordBar.swift
+// ShenYin
+//
+// Created by liangshi on 2025/8/27.
+//
+
+enum Chinese2EnglishRecordBarSate:Int{
+ case start
+ case stop
+}
+
+protocol Chinese2EnglishRecordBarDelegate:NSObject {
+ func recordBarLanguageChange(_ bar:Chinese2EnglishRecordBar)
+ func recordBar(_ bar:Chinese2EnglishRecordBar,stateChange state:Chinese2EnglishRecordBarSate)
+}
+
+class Chinese2EnglishRecordBar: BaseView {
+ let recordBtn = LoadingButton()
+ let leftItem = RecordBarItem()
+ let rightItem = RecordBarItem()
+ weak var delegate:Chinese2EnglishRecordBarDelegate?
+ var isChienseEnglish = false{
+ didSet{
+ if isChienseEnglish {
+ leftItem.icon.isHidden = true
+ rightItem.icon.isHidden = true
+ }
+ else{
+ leftItem.icon.isHidden = false
+ rightItem.icon.isHidden = false
+ }
+ }
+ }
+
+ override func setupViews() {
+ backgroundColor = .color(.bgColor)
+ addSubviews([leftItem,rightItem,recordBtn])
+
+ recordBtn.do { v in
+ v.setImage(UIImage(named: "btn_record_normal"), for: .normal)
+ v.setImage(UIImage(named: "btn_record_stop"), for: .selected)
+ v.addTarget(self, action: #selector(recordBtnAction), for: .touchUpInside)
+ }
+ leftItem.do { (v) in
+ v.language = CCAiLanguage.chinse
+ v.yc.addTap(target: self, action: #selector(leftAction))
+ }
+ rightItem.do { (v) in
+
+ v.language = CCAiLanguage.english
+ v.yc.addTap(target: self, action: #selector(rightAction))
+ }
+ }
+
+ override func setupLayout() {
+ recordBtn.snp.makeConstraints { make in
+ make.width.equalTo(100)
+ make.height.equalTo(50)
+ make.center.equalToSuperview()
+ }
+ leftItem.snp.makeConstraints { make in
+ make.height.equalTo(56)
+ make.centerY.equalTo(recordBtn)
+ make.right.equalToSuperview().offset(-(kScreenWid/2 + 70))
+ }
+ rightItem.snp.makeConstraints { make in
+ make.height.equalTo(56)
+ make.centerY.equalTo(recordBtn)
+ make.left.equalToSuperview().offset(kScreenWid/2 + 70)
+ }
+ }
+ func startAnimating(){
+ leftItem.alpha = 0.3
+ rightItem.alpha = 0.3
+ recordBtn.startAnimating()
+ recordBtn.activeView.backgroundColor = .color(.bgColor)
+ }
+ func stopAnimation(){
+ leftItem.alpha = 1
+ rightItem.alpha = 1
+ }
+ @objc func recordBtnAction(){
+ if recordBtn.activeView.animating {
+ return
+ }
+ recordBtn.isSelected = !recordBtn.isSelected
+ if recordBtn.isSelected {
+ leftItem.alpha = 0.3
+ rightItem.alpha = 0.3
+ }
+ else{
+ leftItem.alpha = 1
+ rightItem.alpha = 1
+ }
+
+ if recordBtn.isSelected {
+ delegate?.recordBar(self, stateChange: .start)
+ }
+ else{
+ delegate?.recordBar(self, stateChange: .stop)
+ }
+ }
+
+ @objc func leftAction(){
+ if isChienseEnglish {
+ return
+ }
+ if recordBtn.activeView.animating {
+ return
+ }
+ if recordBtn.isSelected {
+ return
+ }
+ let v = LanguagePickerView(languages: CCAiLanguage.all,isLeft: true,left: leftItem.language,right: rightItem.language)
+ v.selectedIndex = v.list.firstIndex(where: {$0.title == leftItem.language.title}) ?? 0
+ v.show()
+ v.didSelected = {[weak self] (index,value) in
+ guard let self = self else { return }
+ if index == 0 {
+ leftItem.language = value
+ }
+ else{
+ rightItem.language = value
+ }
+ delegate?.recordBarLanguageChange(self)
+ }
+ }
+ @objc func rightAction(){
+ if isChienseEnglish {
+ return
+ }
+ if recordBtn.activeView.animating {
+ return
+ }
+ if recordBtn.isSelected {
+ return
+ }
+ let v = LanguagePickerView(languages: CCAiLanguage.all,isLeft: false,left: leftItem.language,right: rightItem.language)
+ v.selectedIndex = v.list.firstIndex(where: {$0.title == rightItem.language.title}) ?? 0
+ v.show()
+ v.didSelected = {[weak self] (index,value) in
+ guard let self = self else { return }
+ if index == 0 {
+ leftItem.language = value
+ }
+ else{
+ rightItem.language = value
+ }
+ delegate?.recordBarLanguageChange(self)
+ }
+ }
+
+ class RecordBarItem: BaseView {
+ let icon = UIImageView()
+ let titleLabel = UILabel()
+ let valueLabel = UILabel()
+
+ var language:CCAiLanguage = CCAiLanguage.chinse{
+ didSet{
+ titleLabel.text = language.title
+ }
+ }
+
+ override func setupViews() {
+// backgroundColor = .red
+ addSubviews([titleLabel,valueLabel,icon])
+ icon.do { v in
+ v.image = UIImage(named: "polygon")
+ }
+ titleLabel.do { v in
+ v.textColor = .color(.level1)
+ v.font = .bold(16)
+ }
+ valueLabel.do { v in
+ v.textColor = .color(.level2)
+ v.font = .regular(10)
+ }
+ }
+
+ override func setupLayout() {
+ icon.snp.makeConstraints { make in
+ make.size.equalTo(12)
+ make.top.equalToSuperview().inset(10)
+ make.right.equalToSuperview()
+ }
+ titleLabel.snp.makeConstraints { make in
+ make.right.equalTo(icon.snp.left).offset(-5)
+ make.centerY.equalTo(icon)
+ make.left.equalToSuperview()
+ }
+ valueLabel.snp.makeConstraints { make in
+ make.right.equalTo(titleLabel)
+ make.top.equalTo(titleLabel.snp.bottom).offset(5)
+ }
+ }
+ }
+}
--- /dev/null
+//
+// Untitled.swift
+// ShenYin
+//
+// Created by liangshi on 2026/4/8.
+//
+
+//
+// DialogRecordBar.swift
+// ShenYin
+//
+// Created by liangshi on 2025/9/16.
+//
+import DGActivityIndicatorView
+
+enum DialogRecordDeviceType{
+ case earphone
+ case phone
+}
+enum DialogRecordDeviceState{
+ case start
+ case stop
+}
+enum DialogRecordLayoutType{
+ case normal
+ case spolit
+}
+protocol DialogRecordBarDelegate:NSObject {
+ func recordBar(_ bar:DialogRecordBar,layoutChange :DialogRecordLayoutType)
+ func recordBar(_ bar:DialogRecordBar, device:DialogRecordDeviceType,stateChange state:DialogRecordDeviceState)
+}
+
+extension UIView{
+ static let converView = UIView()
+ func updateConnectState(_ state:Bool) {
+ if state {
+ if UIView.converView.superview == nil {
+ return
+ }
+ self.alpha = 1
+ UIView.converView.removeFromSuperview()
+ }
+ else{
+ if UIView.converView.superview != nil {
+ return
+ }
+ self.alpha = 0.3
+ UIView.converView.backgroundColor = .clear
+ self.addSubview(UIView.converView)
+ UIView.converView.snp.makeConstraints { make in
+ make.edges.equalToSuperview()
+ }
+ }
+ }
+}
+
+class DialogRecordBar: BaseView {
+ let leftItem = DialogItem()
+ let rightItem = DialogItem()
+ let switchBtn = UIButton()
+
+ weak var delegate:DialogRecordBarDelegate?
+ var navBar:BaseNavigationBar = BaseNavigationBar()
+
+ var isBusy:Bool{
+ return leftItem.recordItem.activeView.animating || leftItem.recordItem.loadView.animating || rightItem.recordItem.activeView.animating || rightItem.recordItem.loadView.animating
+ }
+
+ override func setupViews() {
+ backgroundColor = .clear
+
+ addSubviews([leftItem,rightItem,switchBtn])
+ switchBtn.do { v in
+ v.setImage(UIImage(named: "split_screen_1"), for: .normal)
+ v.setImage(UIImage(named: "split_screen_2"), for: .selected)
+ v.addTarget(self, action: #selector(switchBtnAction), for: .touchUpInside)
+ }
+ leftItem.do { v in
+ v.recordItem.setImage(UIImage(named: "dialog_device_ear"), for: .normal)
+ v.recordItem.setImage(UIImage(named: "dialog_device_ear"), for: .selected)
+
+ v.recordItem.addTarget(self, action: #selector(leftRecordBtnAction), for: .touchUpInside)
+ v.languageItem.yc.addTap(target: self, action: #selector(leftLanguageAction))
+ v.languageItem.language = AiLanguageCache.get(type: .dialog_left) ?? .chinse
+ }
+ rightItem.do { v in
+ v.recordItem.setImage(UIImage(named: "dialog_device_phone"), for: .normal)
+ v.recordItem.setImage(UIImage(named: "dialog_device_phone"), for: .selected)
+
+
+ v.recordItem.addTarget(self, action: #selector(rightRecordBtnAction), for: .touchUpInside)
+ v.languageItem.yc.addTap(target: self, action: #selector(rightLanguageAction))
+ v.languageItem.language = AiLanguageCache.get(type: .dialog_right) ?? .english
+ }
+ }
+
+ override func setupLayout() {
+ switchBtn.snp.remakeConstraints { make in
+ make.size.equalTo(38)
+ make.centerX.equalToSuperview()
+ make.top.equalToSuperview().inset(10)
+ }
+ leftItem.snp.remakeConstraints { make in
+ make.width.equalTo(100)
+ make.height.equalTo(98)
+ make.top.equalToSuperview().inset(10)
+ make.right.equalToSuperview().offset(-(kScreenWid/2 + 60))
+ }
+ rightItem.snp.remakeConstraints { make in
+ make.width.height.equalTo(leftItem)
+ make.top.equalToSuperview().inset(10)
+ make.left.equalToSuperview().offset(kScreenWid/2 + 60)
+ }
+ }
+ func splitLayout(){
+ switchBtn.snp.remakeConstraints { make in
+ make.size.equalTo(38)
+ make.right.equalToSuperview().inset(36)
+ make.top.equalToSuperview().inset(10)
+ }
+ leftItem.snp.remakeConstraints { make in
+ make.width.equalTo(100)
+ make.height.equalTo(98)
+ make.top.equalToSuperview().inset(10)
+ make.right.equalToSuperview().offset(-(kScreenWid/2 - 33))
+ }
+ }
+ func stopRecord(_ type:DialogRecordDeviceType){
+ if type == .earphone {
+ leftItem.recordItem.isSelected = false
+ leftItem.recordItem.stopAnimating(finished: { [weak self] in
+ guard let self = self else { return }
+ leftItem.recordItem.alpha = 1
+ leftItem.languageItem.alpha = 1
+ rightItem.recordItem.alpha = 1
+ rightItem.languageItem.alpha = 1
+ })
+ }
+ else{
+ rightItem.recordItem.isSelected = false
+ rightItem.recordItem.stopAnimating(finished: { [weak self] in
+ guard let self = self else { return }
+ leftItem.recordItem.alpha = 1
+ leftItem.languageItem.alpha = 1
+ rightItem.recordItem.alpha = 1
+ rightItem.languageItem.alpha = 1
+ })
+ }
+ }
+ override func setupData() {
+ NotificationManager.add(self, selector: #selector(deviceChange), forName: .deviceValidChange)
+ }
+ @objc func deviceChange(){
+ self.updateConnectState(CCBleManager.shared.isConneted)
+ }
+
+ @objc func switchBtnAction(){
+ switchBtn.isSelected = !switchBtn.isSelected
+ let type:DialogRecordLayoutType = switchBtn.isSelected ? .spolit:.normal
+ delegate?.recordBar(self, layoutChange: type)
+
+ if type == .normal {
+ navBar.titleLabel.isHidden = false
+ addSubview(rightItem)
+ setupLayout()
+ rightItem.setupLayout()
+ navBar.frame = CGRectMake(0, 0, kScreenWid, kNavBtm)
+ rightItem.transform = CGAffineTransform(rotationAngle: .pi*2)
+ }
+ else{
+ splitLayout()
+ rightItem.setupLayout()
+ rightItem.transform = CGAffineTransform(rotationAngle: .pi)
+
+ navBar.titleLabel.isHidden = true
+ navBar.addSubview(rightItem)
+ navBar.frame = CGRectMake(0, 0, kScreenWid, CCConfig.dialogRecordBarHeight)
+ navBar.superview?.bringSubviewToFront(navBar)
+ rightItem.snp.remakeConstraints { make in
+ make.centerX.equalToSuperview()
+ make.bottom.equalToSuperview()
+ make.width.height.equalTo(leftItem)
+ }
+ }
+ }
+
+ @objc func leftRecordBtnAction(){
+ if rightItem.recordItem.activeView.animating || rightItem.recordItem.loadView.animating || leftItem.recordItem.loadView.animating{
+ return
+ }
+ if leftItem.recordItem.activeView.animating{
+ delegate?.recordBar(self, device: .earphone,stateChange: .stop)
+ stopRecord(.earphone)
+ return
+ }
+
+ leftItem.recordItem.isSelected = !leftItem.recordItem.isSelected
+ if leftItem.recordItem.isSelected {
+ leftItem.recordItem.alpha = 1
+ leftItem.languageItem.alpha = 0.3
+ rightItem.recordItem.alpha = 0.3
+ rightItem.languageItem.alpha = 0.3
+
+ leftItem.recordItem.startAnimating()
+ delegate?.recordBar(self, device: .earphone,stateChange: .start)
+ }
+ else{
+ stopRecord(.earphone)
+ delegate?.recordBar(self, device: .earphone,stateChange: .stop)
+ }
+ }
+ @objc func rightRecordBtnAction(){
+ if leftItem.recordItem.activeView.animating || leftItem.recordItem.loadView.animating || rightItem.recordItem.loadView.animating{
+ return
+ }
+ if rightItem.recordItem.activeView.animating{
+ stopRecord(.phone)
+ delegate?.recordBar(self, device: .phone,stateChange: .stop)
+ return
+ }
+
+ rightItem.recordItem.isSelected = !rightItem.recordItem.isSelected
+
+ if rightItem.recordItem.isSelected {
+ leftItem.recordItem.alpha = 0.3
+ leftItem.languageItem.alpha = 0.3
+ rightItem.recordItem.alpha = 1
+ rightItem.languageItem.alpha = 0.3
+
+ rightItem.recordItem.startAnimating()
+ delegate?.recordBar(self, device: .phone,stateChange: .start)
+ }
+ else{
+ stopRecord(.phone)
+ delegate?.recordBar(self, device: .phone,stateChange: .stop)
+ }
+ }
+
+ @objc func leftLanguageAction(){
+ if self.isBusy {
+ return
+ }
+ let v = LanguagePickerView(languages: CCAiLanguage.all,isLeft: true,left: leftItem.languageItem.language,right: rightItem.languageItem.language)
+ v.selectedIndex = v.list.firstIndex(where: {$0.title == leftItem.languageItem.language.title}) ?? 0
+ v.show()
+ v.didSelected = {[weak self] (index,value) in
+ guard let self = self else { return }
+ if index == 0 {
+ leftItem.languageItem.language = value
+ AiLanguageCache.save(type: .dialog_left, lan: value)
+ }
+ else{
+ rightItem.languageItem.language = value
+ AiLanguageCache.save(type: .dialog_right, lan: value)
+ }
+ }
+ }
+ @objc func rightLanguageAction(){
+ if self.isBusy{
+ return
+ }
+ let v = LanguagePickerView(languages: CCAiLanguage.all,isLeft: false,left: leftItem.languageItem.language,right: rightItem.languageItem.language)
+ v.selectedIndex = v.list.firstIndex(where: {$0.title == rightItem.languageItem.language.title}) ?? 0
+ v.show()
+ v.didSelected = {[weak self] (index,value) in
+ guard let self = self else { return }
+ if index == 0 {
+ leftItem.languageItem.language = value
+ AiLanguageCache.save(type: .dialog_left, lan: value)
+ }
+ else{
+ rightItem.languageItem.language = value
+ AiLanguageCache.save(type: .dialog_right, lan: value)
+ }
+ }
+ }
+
+ class DialogItem: UIView {
+ let languageItem = RecordLanguageItem()
+ let recordItem = DialogRecordingButton()
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ setupViews()
+ setupLayout()
+ }
+
+ @MainActor required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ func setupViews() {
+// backgroundColor = .yellow
+ addSubviews([languageItem,recordItem])
+ }
+
+ func setupLayout() {
+ recordItem.snp.remakeConstraints { make in
+ make.width.equalToSuperview()
+ make.height.equalTo(50)
+ make.top.equalToSuperview().inset(0)
+ make.centerX.equalToSuperview()
+ }
+ languageItem.snp.remakeConstraints { make in
+ make.height.equalTo(40)
+ make.top.equalTo(recordItem.snp.bottom)
+ make.centerX.equalToSuperview()
+ }
+
+ }
+ }
+ class RecordLanguageItem: BaseView {
+ let icon = UIImageView()
+ let titleLabel = UILabel()
+ let valueLabel = UILabel()
+
+ var language:CCAiLanguage = CCAiLanguage.chinse{
+ didSet{
+ titleLabel.text = language.title
+ }
+ }
+
+ override func setupViews() {
+ addSubviews([titleLabel,valueLabel,icon])
+ icon.do { v in
+ v.image = UIImage(named: "polygon")
+ }
+ titleLabel.do { v in
+ v.textColor = .color(.level1)
+ v.font = .bold(16)
+ }
+ valueLabel.do { v in
+ v.textColor = .color(.level2)
+ v.font = .regular(10)
+ }
+ }
+
+ override func setupLayout() {
+ icon.snp.makeConstraints { make in
+ make.size.equalTo(12)
+ make.top.equalToSuperview().inset(10)
+ make.right.equalToSuperview()
+ }
+ titleLabel.snp.makeConstraints { make in
+ make.right.equalTo(icon.snp.left).offset(-5)
+ make.centerY.equalTo(icon)
+ make.left.equalToSuperview()
+ }
+ valueLabel.snp.makeConstraints { make in
+ make.right.equalTo(titleLabel)
+ make.top.equalTo(titleLabel.snp.bottom).offset(5)
+ make.bottom.equalToSuperview().inset(12)
+ }
+ }
+ }
+
+ class DialogRecordingButton:UIButton{
+ let activeView = DGActivityIndicatorView(type: .lineScalePulseOut,tintColor: UIColor.white,size: 25)!
+ let loadView = DGActivityIndicatorView(type: .ballClipRotate,tintColor: UIColor.white)!
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ activeView.backgroundColor = .color(.theme)
+ activeView.yc.setCornerRadius(25)
+ addSubview(activeView)
+ activeView.snp.remakeConstraints { make in
+ make.edges.equalToSuperview()
+ }
+
+ loadView.yc.setCornerRadius(25)
+ loadView.backgroundColor = .color(.theme)
+ addSubview(loadView)
+ loadView.snp.remakeConstraints { make in
+ make.edges.equalToSuperview()
+ }
+
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+ func startAnimating(finished:(()->Void)? = nil){
+ loadView.isHidden = true
+ activeView.isHidden = false
+ activeView.startAnimating()
+ }
+ func stopAnimating(finished:@escaping (()->Void)){
+ activeView.stopAnimating()
+ activeView.isHidden = true
+
+ loadView.isHidden = false
+ loadView.startAnimating()
+ DispatchQueue.main.asyncAfter(deadline:.now() + 0.3) { [weak self] in
+ self?.loadView.stopAnimating()
+ finished()
+ }
+ }
+ }
+
+}
--- /dev/null
+//
+// Untitled.swift
+// ShenYin
+//
+// Created by liangshi on 2025/8/27.
+//
+
+enum RecordSate:Int{
+ case start
+ case stop
+ case resume
+ case pause
+}
+
+protocol FieldRecordBarDelegate:NSObject {
+ func fieldRecordBar(_ bar:FieldRecordBar,languageChange language:CCAiLanguage)
+ func fieldRecordBar(_ bar:FieldRecordBar,stateChange state:RecordSate)
+}
+
+
+class FieldRecordBar: BaseView {
+ let recordBtn = LoadingButton()
+ let leftItem = RecordBarItem()
+ let rightItem = RecordBarButton()
+ var state:RecordSate = .stop
+ weak var delegate:FieldRecordBarDelegate?
+ var hasRightItem:Bool = true
+
+ override func setupViews() {
+ backgroundColor = .color(.cellBg)
+ addSubviews([leftItem,rightItem,recordBtn])
+
+ recordBtn.do { v in
+ v.setImage(UIImage(named: "btn_record_normal"), for: .normal)
+ v.setImage(UIImage(named: "btn_record_stop"), for: .selected)
+ v.addTarget(self, action: #selector(recordBtnAction), for: .touchUpInside)
+ }
+ leftItem.do {v in
+ v.yc.addTap(target: self, action: #selector(leftAction))
+ v.language = .chinse
+ }
+ rightItem.do {v in
+ v.state = .stop
+ v.yc.addTap(target: self, action: #selector(pauseAction))
+ }
+ }
+
+ override func setupLayout() {
+ recordBtn.snp.makeConstraints { make in
+ make.width.equalTo(100)
+ make.height.equalTo(50)
+ make.center.equalToSuperview()
+ }
+ leftItem.snp.makeConstraints { make in
+ make.size.equalTo(56)
+ make.centerY.equalTo(recordBtn)
+ make.right.equalToSuperview().offset(-(kScreenWid/2 + 70))
+ }
+ rightItem.snp.makeConstraints { make in
+ make.size.equalTo(56)
+ make.centerY.equalTo(recordBtn)
+ make.left.equalToSuperview().offset(kScreenWid/2 + 70)
+ }
+ }
+
+ func startAnimating(){
+ leftItem.alpha = 0.3
+ recordBtn.startAnimating()
+ }
+ func stopAnimation(){
+ leftItem.alpha = 1
+ }
+ @objc func leftAction(){
+ if recordBtn.isSelected || recordBtn.activeView.animating {
+ return
+ }
+ let list = CCAiLanguage.all.map{$0.title}
+
+ let v = CustomPicker(title: "请选择语言".l10n, 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.language = CCAiLanguage.all.first(where: {$0.title == value})!
+ delegate?.fieldRecordBar(self, languageChange:leftItem.language)
+ }
+ return
+ }
+ @objc func recordBtnAction(){
+ if recordBtn.activeView.animating {
+ return
+ }
+ recordBtn.isSelected = !recordBtn.isSelected
+ rightItem.state = .start
+ rightItem.isHidden = !recordBtn.isSelected
+
+ if hasRightItem == false{
+ rightItem.isHidden = true
+ }
+
+
+ if recordBtn.isSelected {
+ leftItem.alpha = 0.3
+ }
+ else{
+ leftItem.alpha = 1
+ }
+ if recordBtn.isSelected {
+ delegate?.fieldRecordBar(self, stateChange: .start)
+ }
+ else{
+ delegate?.fieldRecordBar(self, stateChange: .stop)
+ }
+ }
+ @objc func pauseAction(){
+ if rightItem.state == .start {
+ rightItem.state = .pause
+ }
+ else if rightItem.state == .resume {
+ rightItem.state = .pause
+ }
+ else if rightItem.state == .pause {
+ rightItem.state = .resume
+ }
+ delegate?.fieldRecordBar(self, stateChange: rightItem.state)
+ }
+
+ class RecordBarItem: BaseView {
+ private let icon = UIImageView()
+ private let titleLabel = UILabel()
+ var language:CCAiLanguage = .chinse{
+ didSet{
+ titleLabel.text = language.title
+ }
+ }
+ override func setupViews() {
+ addSubviews([titleLabel,icon])
+ icon.do { v in
+ v.image = UIImage(named: "record_select_language")
+ }
+ titleLabel.do { v in
+ v.textColor = .color(.level1)
+ v.font = .regular(10)
+ }
+ }
+
+ override func setupLayout() {
+ icon.snp.makeConstraints { make in
+ make.size.equalTo(28)
+ make.top.equalToSuperview().inset(10)
+ make.centerX.equalToSuperview()
+ }
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalTo(icon.snp.bottom).offset(5)
+ make.centerX.equalTo(icon)
+ }
+ }
+ }
+ class RecordBarButton: BaseView {
+ let icon = UIImageView()
+ let titleLabel = UILabel()
+ var state:RecordSate = .resume{
+ didSet{
+ if state == .start {
+ titleLabel.text = "暂停".l10n
+ icon.image = UIImage(named: "record_pause")
+ }
+ else if state == .resume{
+ titleLabel.text = "暂停".l10n
+ icon.image = UIImage(named: "record_pause")
+ }
+ else if state == .pause{
+ titleLabel.text = "继续".l10n
+ icon.image = UIImage(named: "record_play")
+ }
+ }
+ }
+
+ override func setupViews() {
+ addSubviews([titleLabel,icon])
+ icon.do { v in
+ }
+ titleLabel.do { v in
+ v.textColor = .color(.level1)
+ v.font = .regular(10)
+ }
+ }
+
+ override func setupLayout() {
+ icon.snp.makeConstraints { make in
+ make.size.equalTo(28)
+ make.top.equalToSuperview().inset(10)
+ make.centerX.equalToSuperview()
+ }
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalTo(icon.snp.bottom).offset(5)
+ make.centerX.equalTo(icon)
+ }
+ }
+ }
+}
"scale" : "1x"
},
{
- "filename" : "Group 2104@2x.png",
+ "filename" : "Slice 324@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
- "filename" : "Group 2104@3x.png",
+ "filename" : "Slice 324@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
"scale" : "1x"
},
{
- "filename" : "Group_2122@2x.png",
+ "filename" : "Slice 324@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
- "filename" : "Group_2122@3x.png",
+ "filename" : "Slice 324@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
"scale" : "1x"
},
{
- "filename" : "Group_2437@2x.png",
+ "filename" : "Slice 324@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
- "filename" : "Group_2437@3x.png",
+ "filename" : "Slice 324@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
"scale" : "1x"
},
{
- "filename" : "Group_2435@2x.png",
+ "filename" : "Slice 324@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
- "filename" : "Group_2435@3x.png",
+ "filename" : "Slice 324@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
"scale" : "1x"
},
{
- "filename" : "Frame@2x(2).png",
+ "filename" : "Frame@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
- "filename" : "Frame@3x(2).png",
+ "filename" : "Frame@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Slice 358@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Slice 358@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Slice 359@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Slice 359@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
+++ /dev/null
-{
- "images" : [
- {
- "idiom" : "universal",
- "scale" : "1x"
- },
- {
- "filename" : "Group_2274@2x.png",
- "idiom" : "universal",
- "scale" : "2x"
- },
- {
- "filename" : "Group_2274@3x.png",
- "idiom" : "universal",
- "scale" : "3x"
- }
- ],
- "info" : {
- "author" : "xcode",
- "version" : 1
- }
-}
+++ /dev/null
-{
- "images" : [
- {
- "idiom" : "universal",
- "scale" : "1x"
- },
- {
- "filename" : "Group_2275@2x.png",
- "idiom" : "universal",
- "scale" : "2x"
- },
- {
- "filename" : "Group_2275@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
- }
-}
//
// Created by liangshi on 2025/9/16.
//
+import DGActivityIndicatorView
enum DialogRecordDeviceType{
case earphone
}
protocol DialogRecordBarDelegate:NSObject {
func recordBar(_ bar:DialogRecordBar,layoutChange :DialogRecordLayoutType)
- func recordBar(_ bar:DialogRecordBar, device:DialogRecordDeviceType,stateChange state:RecordBarSate)
+ func recordBar(_ bar:DialogRecordBar, device:DialogRecordDeviceType,stateChange state:DialogRecordDeviceState)
}
extension UIView{
}
}
}
+
+ class DialogRecordingButton:UIButton{
+ let activeView = DGActivityIndicatorView(type: .lineScalePulseOut,tintColor: UIColor.hexString("#919191"),size: 20)!
+ let loadView = DGActivityIndicatorView(type: .ballClipRotate,tintColor: UIColor.hexString("#919191"))!
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ activeView.backgroundColor = .color(.bgColor)
+ activeView.yc.setBorder(width: 2, color: .hexString("#919191"), radius: 17)
+ addSubview(activeView)
+ activeView.snp.remakeConstraints { make in
+ make.edges.equalToSuperview()
+ }
+
+ addSubview(loadView)
+ loadView.snp.remakeConstraints { make in
+ make.edges.equalToSuperview()
+ }
+ loadView.backgroundColor = .color(.bgColor)
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+ func startAnimating(finished:(()->Void)? = nil){
+ loadView.isHidden = true
+ activeView.isHidden = false
+ activeView.startAnimating()
+ }
+ func stopAnimating(finished:@escaping (()->Void)){
+ activeView.stopAnimating()
+ activeView.isHidden = true
+
+ loadView.isHidden = false
+ loadView.startAnimating()
+ DispatchQueue.main.asyncAfter(deadline:.now() + 0.3) { [weak self] in
+ self?.loadView.stopAnimating()
+ finished()
+ }
+ }
+ }
+
}
// Created by liangshi on 2025/8/27.
//
-enum RecordBarSate:Int{
+enum Chinese2EnglishRecordBarSate:Int{
case start
case stop
}
-protocol RecordBarDelegate:NSObject {
- func recordBarLanguageChange(_ bar:RecordBar)
- func recordBar(_ bar:RecordBar,stateChange state:RecordBarSate)
+protocol Chinese2EnglishRecordBarDelegate:NSObject {
+ func recordBarLanguageChange(_ bar:Chinese2EnglishRecordBar)
+ func recordBar(_ bar:Chinese2EnglishRecordBar,stateChange state:Chinese2EnglishRecordBarSate)
}
-class RecordBar: BaseView {
+class Chinese2EnglishRecordBar: BaseView {
let recordBtn = LoadingButton()
let leftItem = RecordBarItem()
let rightItem = RecordBarItem()
- weak var delegate:RecordBarDelegate?
+ weak var delegate:Chinese2EnglishRecordBarDelegate?
var isChienseEnglish = false{
didSet{
if isChienseEnglish {
v.isEditable = false
}
backgroundColor = .color(.bgColor)
+// if CCConfig.appType == .paxa {
+// backgroundColor = .white
+// yc.setCornerRadius(8)
+// }
}
override func setupLayout() {
activeView.stopAnimating()
}
}
-class DialogRecordingButton:UIButton{
- let activeView = DGActivityIndicatorView(type: .lineScalePulseOut,tintColor: UIColor.hexString("#919191"),size: 20)!
- let loadView = DGActivityIndicatorView(type: .ballClipRotate,tintColor: UIColor.hexString("#919191"))!
-
- override init(frame: CGRect) {
- super.init(frame: frame)
- activeView.backgroundColor = .color(.bgColor)
- activeView.yc.setBorder(width: 2, color: .hexString("#919191"), radius: 17)
- addSubview(activeView)
- activeView.snp.remakeConstraints { make in
- make.edges.equalToSuperview()
- }
-
- addSubview(loadView)
- loadView.snp.remakeConstraints { make in
- make.edges.equalToSuperview()
- }
- loadView.backgroundColor = .color(.bgColor)
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- func startAnimating(finished:(()->Void)? = nil){
- loadView.isHidden = true
- activeView.isHidden = false
- activeView.startAnimating()
- }
- func stopAnimating(finished:@escaping (()->Void)){
- activeView.stopAnimating()
- activeView.isHidden = true
-
- loadView.isHidden = false
- loadView.startAnimating()
- DispatchQueue.main.asyncAfter(deadline:.now() + 0.3) { [weak self] in
- self?.loadView.stopAnimating()
- finished()
- }
- }
-}
v.font = .regular(12)
}
playBtn.do { v in
- v.setImage(UIImage(named: "record_play 3"), for: .normal)
- v.setImage(UIImage(named: "record_pause 3"), for: .selected)
+ v.setImage(UIImage(named: "pop_play"), for: .normal)
+ v.setImage(UIImage(named: "pop_pause"), for: .selected)
v.addTarget(self, action: #selector(btnAction), for: .touchUpInside)
v.isEnabled = false
}
m.left.right.equalToSuperview()
}
slider.snp.makeConstraints { make in
- // make.width.equalTo(200)
make.height.equalTo(40)
make.centerX.equalToSuperview()
make.left.right.equalToSuperview().inset(40)
make.top.equalTo(slider.snp.bottom)
}
playBtn.snp.makeConstraints { make in
- make.size.equalTo(60)
+ make.size.equalTo(CCConfig.popPlaySize)
make.centerX.equalToSuperview()
make.bottom.equalToSuperview().inset(20)
}