Commit 9178e040 authored by yqz's avatar yqz

完整项目

parent 3be4d5e1
......@@ -220,7 +220,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = SpeakEasyLearnEnglish/SpeakEasyLearnEnglish.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = 6K23946NQ5;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GENERATE_INFOPLIST_FILE = YES;
......@@ -229,6 +229,7 @@
INFOPLIST_KEY_NSCameraUsageDescription = "We need to use your camera to change the avatar";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "Microphone permission is required for voice input";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "We need to use your photo album to change your profile picture";
INFOPLIST_KEY_NSSpeechRecognitionUsageDescription = "Requires your speech recognition to process audio";
INFOPLIST_KEY_NSUserTrackingUsageDescription = "We need your permission to track your usage habits in order to provide a more personalized advertising experience";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
......@@ -259,7 +260,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = SpeakEasyLearnEnglish/SpeakEasyLearnEnglish.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = 6K23946NQ5;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GENERATE_INFOPLIST_FILE = YES;
......@@ -268,6 +269,7 @@
INFOPLIST_KEY_NSCameraUsageDescription = "We need to use your camera to change the avatar";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "Microphone permission is required for voice input";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "We need to use your photo album to change your profile picture";
INFOPLIST_KEY_NSSpeechRecognitionUsageDescription = "Requires your speech recognition to process audio";
INFOPLIST_KEY_NSUserTrackingUsageDescription = "We need your permission to track your usage habits in order to provide a more personalized advertising experience";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
......
......@@ -50,6 +50,7 @@ extension AppDelegate {
break
case .WIFI,.WWAN:
self.Purchase()
SpeakIAPConfigs.share.loadData()
let hadStart = UserDefaults.standard.value(forKey: "report_app_first_start") as? Bool ?? false
if hadStart == false {
UserDefaults.standard.set(true, forKey: "report_app_first_start")
......
......@@ -129,4 +129,5 @@ class SpeakTitleView: UIView {
right.isHidden = true
return right
}()
}
......@@ -157,6 +157,12 @@ class AttributedStringBuilder {
return self
}
@discardableResult
func underlineColor(_ color:UIColor = .gray) -> Self {
attributes[.underlineColor] = color
return self
}
/// 设置删除线
@discardableResult
func strikethrough(_ style: NSUnderlineStyle = .single) -> Self {
......@@ -164,6 +170,13 @@ class AttributedStringBuilder {
return self
}
/// 设置删除线
@discardableResult
func strikethColor(_ color:UIColor = .gray) -> Self {
attributes[.strikethroughColor] = color
return self
}
/// 设置段落样式
@discardableResult
func paragraphStyle(_ alignment: NSTextAlignment = .left, lineSpacing: CGFloat = 0) -> Self {
......
......@@ -35,6 +35,9 @@ class SpeakUserNetViewModel: NetworkUtil<UserAPI> {
switch result {
case .success(let res):
response(res.status == 200)
if res.status != 200 {
SpWindow.rootViewController?.Alert(message: res.msg ?? "" ,afterClose: 1.5)
}
break
case .failure(_):
response(false)
......
......@@ -15,12 +15,18 @@ class SpeakChangeAIViewCtr: SpeakEleBaseViewCtr {
@IBOutlet weak var SpeakBottomConst: NSLayoutConstraint!
@IBOutlet weak var SpeakTTTTTTT: UIView!
override func viewDidLoad() {
super.viewDidLoad()
SpeakBottomConst.constant = -Dev.screenH
self.view.backgroundColor = .init(hex: 0x000000,alpha: 0.8)
AISer = viewModel.AIser()
self.SpeakTTTTTTT.gesture(target: self, class: UITapGestureRecognizer.self, selector: #selector(cloassssssss(_:)))
}
@objc func cloassssssss(_ res:UIGestureRecognizer) -> Void {
self.dismiss(animated: true)
}
override func viewWillAppear(_ animated: Bool) {
......@@ -29,10 +35,12 @@ class SpeakChangeAIViewCtr: SpeakEleBaseViewCtr {
self.view.layoutIfNeeded()
self.view.setNeedsDisplay()
DispatchQueue.main.async {
self.SpeakChangeAITableView.reloadData()
UIView.animate(withDuration: 0.25) {
self.SpeakBottomConst.constant = 0
self.view.layoutIfNeeded()
if self.SpeakBottomConst.constant != 0 {
self.SpeakChangeAITableView.reloadData()
UIView.animate(withDuration: 0.25) {
self.SpeakBottomConst.constant = 0
self.view.layoutIfNeeded()
}
}
}
}
......@@ -79,6 +87,7 @@ extension SpeakChangeAIViewCtr : UITableViewDelegate , UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: SpeakChangeAITableViewCell.id, for: indexPath) as! SpeakChangeAITableViewCell
cell.data = self.AISer[indexPath.section]
cell.selectionStyle = .none
return cell
}
......
......@@ -14,6 +14,7 @@
<outlet property="SpeakBottomConst" destination="8YU-WL-X17" id="Hlp-29-BtJ"/>
<outlet property="SpeakChangeAITableView" destination="Vgo-je-sC0" id="SjX-Qc-xzF"/>
<outlet property="SpeakContentV" destination="54J-8Z-htx" id="fbh-Sf-yQ5"/>
<outlet property="SpeakTTTTTTT" destination="ZnI-l1-wFV" id="SF2-GZ-fMh"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
......@@ -22,6 +23,10 @@
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZnI-l1-wFV">
<rect key="frame" x="0.0" y="0.0" width="393" height="255.66666666666666"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="54J-8Z-htx">
<rect key="frame" x="0.0" y="255.66666666666669" width="393" height="596.33333333333326"/>
<subviews>
......@@ -79,9 +84,13 @@
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.80117984693877553" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="54J-8Z-htx" secondAttribute="bottom" id="8YU-WL-X17"/>
<constraint firstItem="54J-8Z-htx" firstAttribute="top" secondItem="ZnI-l1-wFV" secondAttribute="bottom" id="EEc-3L-vSQ"/>
<constraint firstItem="ZnI-l1-wFV" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="PbW-cl-Eog"/>
<constraint firstItem="ZnI-l1-wFV" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="d0k-LC-KCC"/>
<constraint firstItem="54J-8Z-htx" firstAttribute="height" secondItem="i5M-Pr-FkT" secondAttribute="height" multiplier="0.7" id="fX2-sc-jaP"/>
<constraint firstItem="54J-8Z-htx" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="iWb-ad-0TK"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="54J-8Z-htx" secondAttribute="trailing" id="kJp-G3-H1y"/>
<constraint firstItem="fnl-2z-Ty3" firstAttribute="trailing" secondItem="ZnI-l1-wFV" secondAttribute="trailing" id="twN-Fa-A8n"/>
</constraints>
<point key="canvasLocation" x="131" y="-12"/>
</view>
......
......@@ -152,6 +152,10 @@ class SpeakEleHomeViewCtr: SpeakEleBaseViewCtr, UIPopoverPresentationControllerD
}
@IBAction func ShowPro(_ sender: Any) {
if IAPViewModel.share.isSubscribed {
Alert(message: "You have unlocked all the benefits")
return
}
let iap = SpeakEleIAPViewCtr()
iap.state = .other
self.navigationController?.AnimationState = .present
......@@ -273,7 +277,6 @@ extension SpeakEleHomeViewCtr {
self?.navigationController?.pushViewController(iap, animated: true)
}
let data = SpeakLessonDescpModel()
data.id = idx?.lessonId
data.name = idx?.lessonName
......@@ -284,7 +287,6 @@ extension SpeakEleHomeViewCtr {
data.description = idx?.description
data.grammarList = idx?.grammarList
if idx?.isLocked == true {
let alert = SpeakPublicTipsViewCtr(configs: SpeakPublicTipsViewCtr.PublicTipsModel(icon: UIImage(named: "img_course"),title: "skip a grade?",descAttr: "Do you want to unlock all courses immediately",sureAction: "Yes, unlock immediately",cancel: "Wait a minute"))
alert.show()
......@@ -349,12 +351,14 @@ extension SpeakEleHomeViewCtr {
make.bottom.equalToSuperview().inset(Dev.safeAreaInsets.bottom + 50)
}
topButton.snp.makeConstraints { make in
make.bottom.equalTo(-(tabbarHeight + 18))
make.bottom.equalTo(mainScrollview.snp.bottom).offset(15)
make.right.equalTo(self.view.snp.right).offset(-16)
// make.size.equalTo(CGSize(width: 48, height: 48))
}
freeTalk.snp.makeConstraints { make in
make.left.equalToSuperview().inset(16)
make.top.equalTo(topButton.snp.top)
make.centerY.equalTo(topButton.snp.centerY)
// make.size.equalTo(CGSize(width: 48, height: 55))
}
}
......
......@@ -67,6 +67,7 @@ class SpeakNewUserViewCtr: SpeakEleBaseViewCtr {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
AudioPlayerManager.shared.isMute = self.isMute
viewModel.SpeakUpdate = { [weak self] data in
if data is SpeakNetBaseDeflutMode {
self?.SpeakLeassonCollect.isSelected = !(self?.SpeakLeassonCollect.isSelected ?? false)
......@@ -167,6 +168,7 @@ class SpeakNewUserViewCtr: SpeakEleBaseViewCtr {
@IBAction func SoundTapCloseTaps(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
isMute = sender.isSelected
AudioPlayerManager.shared.isMute = self.isMute
AudioPlayerManager.shared.setVolume(sender.isSelected ? 0 : 1)
for (i,_) in self.dataSource.enumerated() {
if let cell = self.SpeakLeassonTableView.cellForRow(at: IndexPath(row: i, section: 0)) as? SpeakDialogAIerCell {
......
......@@ -103,11 +103,12 @@ class SpeakTipssssssViewCtr: UIViewController {
}
@IBAction func SpeakCollectTaps(_ sender: UIButton) {
ProviewModel.collect(param: ["businessId":Int(data?.lessonId ?? "") ?? 0,
sender.isSelected = !sender.isSelected
ProviewModel.collect(param: ["businessId":Int(data?.id ?? 0),
"type":1,
"isCollect":!sender.isSelected]) { (su, data:SpeakNetBaseDeflutMode?) in
if su {
sender.isSelected = !sender.isSelected
}
}
}
......
......@@ -78,6 +78,7 @@
<constraint firstItem="gOj-dx-ibh" firstAttribute="centerY" secondItem="dxx-We-kd6" secondAttribute="centerY" id="3K1-gJ-Ihn"/>
<constraint firstItem="gOj-dx-ibh" firstAttribute="leading" secondItem="dxx-We-kd6" secondAttribute="leading" constant="12" id="3by-CF-3Ay"/>
<constraint firstAttribute="height" constant="60" id="Ph4-XL-DGh"/>
<constraint firstItem="hEl-Xw-qfC" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="gOj-dx-ibh" secondAttribute="trailing" constant="30" id="TxS-7n-eWf"/>
<constraint firstAttribute="trailing" secondItem="hEl-Xw-qfC" secondAttribute="trailing" constant="12" id="Vck-Jx-dBV"/>
<constraint firstItem="hEl-Xw-qfC" firstAttribute="centerY" secondItem="dxx-We-kd6" secondAttribute="centerY" id="cDf-B1-ETx"/>
</constraints>
......@@ -301,7 +302,7 @@
</button>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iq0-j1-0oV">
<button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="1000" verticalHuggingPriority="1000" horizontalCompressionResistancePriority="1000" verticalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iq0-j1-0oV">
<rect key="frame" x="305" y="12" width="28" height="28"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" image="sp-pra-heart"/>
......
......@@ -171,6 +171,9 @@ extension SpeakEleProfileViewCtr : UITableViewDelegate,UITableViewDataSource {
let st = viewModel.setting[safe:indexPath.section]?.child?[indexPath.row]
switch st?.title {
case .TargetLanguage , .NativeLanguage ,.Interest ,.Target:
if st?.title == .TargetLanguage && !IAPViewModel.share.isSubscribed {
return
}
let more = SpeakProfileMoreViewCtr(state: st?.title ?? .TargetLanguage)
self.navigationController?.pushViewController(more, animated: true)
break
......@@ -194,7 +197,9 @@ extension SpeakEleProfileViewCtr : UITableViewDelegate,UITableViewDataSource {
self.parent?.navigationController?.pushViewController(web, animated: true)
break
case .Delete:
SpeakAlertHUD.share.show()
viewModel.deleteAccount { [weak self] in
SpeakAlertHUD.share.disMiss()
self?.deleteAccount()
}
break
......
......@@ -30,6 +30,7 @@ class SpeakEleDebriefViewCtr: SpeakEleBaseViewCtr {
}else{
self.title = "Debrief"
}
self.NoDataView.isHidden = true
SpeakAlertHUD.share.show()
viewModel.correctList(param: ["isError":state == .correct ? 1 : 0]) {[weak self] (su, data:[SpeakProgressCorrect]?) in
if su {
......
......@@ -116,7 +116,10 @@ extension SpeakEleProgressViewCtr: UITableViewDelegate,UITableViewDataSource {
self?.selectIdx = g
self?.loadDataBT()
self?.view.layoutIfNeeded()
tableView.reloadData()
cell.selectIdx = g
cell.data = self?.dayStudy ?? []
self?.view.layoutIfNeeded()
// tableView.reloadData()
}
}
cell.selectionStyle = .none
......
......@@ -20,6 +20,7 @@ class SpeakProgressHistoryViewCtr: SpeakEleBaseViewCtr {
super.viewDidLoad()
self.title = "History class records"
self.view.backgroundColor = .init(hex: 0xF6F7F9)
self.noDataView.isHidden = true
viewModel.historyRecord { [weak self] (su, data:[SpeakProgressHisLessasMode]?) in
if su {
self?.datasource = data ?? []
......
......@@ -147,6 +147,7 @@ class SpeakFreeTalkCallViewCtr: SpeakEleBaseViewCtr {
super.viewWillAppear(animated)
titleView.isHidden = true
SpeakSoundBtn.isSelected = isMate
AudioPlayerManager.shared.isMute = isMate
let aiser = viewModel.AIser()
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
let idx = SpeakElePublicManager.share.PublicData.AIerIndex
......@@ -242,6 +243,7 @@ class SpeakFreeTalkCallViewCtr: SpeakEleBaseViewCtr {
@IBAction func SpeakSoundTaps(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
isMate = sender.isSelected
AudioPlayerManager.shared.isMute = isMate
AudioPlayerManager.shared.setVolume(isMate ? 0 : 1)
}
......
......@@ -68,7 +68,7 @@ class SpeakFreeTalkViewCtr: SpeakEleBaseViewCtr {
self.didddd.isPaused = false
studyTm = SpeakDayEveryManager.manager.SpeakDayData.studyFreeTm ?? 0
studyTime = SpeakDayEveryManager.manager.SpeakDayData.studytime ?? 0
AudioPlayerManager.shared.isMute = self.isMute
SentAudioSound.isSelected = isMute
SpeakVideoPPPPPP.addSubview(SpeakAIVideoPlayManager.share)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
......@@ -101,6 +101,7 @@ class SpeakFreeTalkViewCtr: SpeakEleBaseViewCtr {
sender.isSelected = !sender.isSelected
isMute = sender.isSelected
viewModel.isMute = isMute
AudioPlayerManager.shared.isMute = self.isMute
AudioPlayerManager.shared.setVolume(sender.isSelected ? 0 : 1)
for (i,_) in self.dataSource.enumerated() {
if let cell = self.SpeakLeassonTableView.cellForRow(at: IndexPath(row: i, section: 0)) as? SpeakDialogAIerCell {
......
......@@ -35,6 +35,7 @@ class SpeakFreeTalkAIReceveCell: UITableViewCell {
}else{
SpeakNavtiveL.text = ""
}
SpeakNavtiveL.isHidden = !(SpeakNavtiveL.text?.count ?? 0 > 0)
SpeakContent.sizeToFit()
SpeakNavtiveL.sizeToFit()
}
......
......@@ -63,6 +63,7 @@ class SpeakFreeTalkViewModel: NetworkUtil<FreeTalkAPI> {
}
private func freeTalk(param:[String:Any]) -> Void {
Print(param)
request(.freeTalk(param)) {[weak self] (result: Result<SpeakNetBaseMode<[SpeakFreeTalkModel]>, Error>) in
self?.isSpeech = true
switch result {
......@@ -100,10 +101,20 @@ class SpeakFreeTalkViewModel: NetworkUtil<FreeTalkAPI> {
}
}
}else{
if let last = self?.freeTalkMsg.last {
if last.role == .loading {
self?.freeTalkMsg.removeLast()
}
}
SpWindow.rootViewController?.Alert(message: res.msg ?? "" ,afterClose: 1.5)
}
break
case .failure(let error):
if let last = self?.freeTalkMsg.last {
if last.role == .loading {
self?.freeTalkMsg.removeLast()
}
}
Print(error.localizedDescription)
break
}
......
......@@ -210,7 +210,12 @@ extension SpeakEleIAPViewCtr {
if self.Products.count > 1 {
if isFree {
if let p = self.Products[safe: 0] {
SpeakPayDescritionL.text = "Unlimited dialogue learning, unlimited answer correction, real-time Al feedback, unlimited word parsing\nFree for 3 days, then \(p?.localizedPrice ?? "--") per week"
let att = "Unlimited dialogue learning, unlimited answer correction, real-time Al feedback, unlimited word parsing\n".attributed().font(UIFont.montserrat(.regular,size: 16)).color(.init(hex: 0x000000,alpha: 0.54)).build().combined(with: [ "Free for 3 days, then \(p?.localizedPrice ?? "--") per week".attributed().font(UIFont.montserrat(.regular,size: 18)).color(.init(hex: 0x000000,alpha: 1)).build() ])
// SpeakPayDescritionL.text = "Unlimited dialogue learning, unlimited answer correction, real-time Al feedback, unlimited word parsing\nFree for 3 days, then \(p?.localizedPrice ?? "--") per week"
SpeakPayDescritionL.attributedText = att
let payDay = Date().Common(day: 3).toStr("MMM dd, yyyy") ?? "--"
SpeakTL1.text = "Today Start"
SpeakTL2.text = "become due \(payDay)"
......@@ -223,7 +228,12 @@ extension SpeakEleIAPViewCtr {
}
}else{
if let p = self.Products[safe: 1] {
SpeakPayDescritionL.text = "Unlimited dialogue learning, unlimited answer correction, real-time Al feedback, unlimited word parsing\n\(p?.localizedPrice ?? "--")/year"
let att = "Unlimited dialogue learning, unlimited answer correction, real-time Al feedback, unlimited word\n".attributed().font(UIFont.montserrat(.regular,size: 16)).color(.init(hex: 0x000000,alpha: 0.54)).build().combined(with: [ "parsing \(p?.localizedPrice ?? "--")/year".attributed().font(UIFont.montserrat(.regular,size: 18)).color(.init(hex: 0x000000,alpha: 1)).build() ])
SpeakPayDescritionL.attributedText = att
// SpeakPayDescritionL.text = "Unlimited dialogue learning, unlimited answer correction, real-time Al feedback, unlimited word parsing\n\(p?.localizedPrice ?? "--")/year"
let week = String(format: "%.2lf", (p?.price.doubleValue ?? 0) / (12*4.0))
SpeakTL1.text = "Per week"
SpeakTL2.text = "One year validity period"
......
......@@ -63,7 +63,7 @@ class SpeakEleFLoginViewCtr: SpeakEleBaseViewCtr {
}
break
case .failure(let error):
self.Alert(message: error.localizedDescription)
self.Alert(message: "Login failed")
break
}
}
......@@ -81,7 +81,7 @@ class SpeakEleFLoginViewCtr: SpeakEleBaseViewCtr {
}
break
case .failure(let error):
self.Alert(message: error.localizedDescription)
self.Alert(message: "Login failed")
break
}
}
......
......@@ -35,6 +35,8 @@ class SpeakEleForgetViewCtr: SpeakEleBaseViewCtr {
}
}else{
Alert(message: "Please enter the correct email address")
}
}
......
......@@ -29,12 +29,12 @@ class SpeakEleLoginGuideCtr: SpeakEleBaseViewCtr {
override func viewDidLoad() {
super.viewDidLoad()
self.startAni()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setDescription()
self.startAni()
}
private func startAni() -> Void {
......@@ -107,19 +107,43 @@ class SpeakEleLoginGuideCtr: SpeakEleBaseViewCtr {
}
private func setDescription() -> Void {
SpeakDescLabel.AddTextTap(["Privacy Policy","Terms of Service."])
// SpeakDescLabel.AddTextTap(["Privacy Policy","Terms of Service."])
let privacy = "Privacy Policy".attributed().font(UIFont.montserrat(.medium,size: 10)).underline(.single).paragraphStyle(.center,lineSpacing: 4).build()
let terms = "Terms of Service.".attributed().font(UIFont.montserrat(.medium,size: 10)).underline(.single).paragraphStyle(.center,lineSpacing: 4).build()
let att = "Proceeding further indicates your agreement to our ".attributed().paragraphStyle(.center,lineSpacing: 4).build().combined(with: [privacy," and ", terms])
let att = "Proceeding further indicates your agreement to our ".attributed().paragraphStyle(.center,lineSpacing: 4).build().combined(with: [privacy,"\nand ", terms])
SpeakDescLabel.attributedText = att
SpeakDescLabel.callblack = { [weak self] text in
guard let v:String = text as? String else { return }
if v == "Privacy Policy" {
self?.PrivacyPolicy()
}else{
self?.TermsOfService()
let tap = UITapGestureRecognizer(target: self, action: #selector(tapClick(_:)))
SpeakDescLabel.isUserInteractionEnabled = true
SpeakDescLabel.addGestureRecognizer(tap)
// SpeakDescLabel.callblack = { [weak self] text in
// guard let v:String = text as? String else { return }
// if v == "Privacy Policy" {
// self?.PrivacyPolicy()
// }else{
// self?.TermsOfService()
// }
// }
}
@objc private func tapClick(_ res:UIGestureRecognizer) -> Void {
let Point = res.location(in: self.SpeakDescLabel)
Print(Point)
self.view.layoutIfNeeded()
let height = self.SpeakDescLabel.height
if Point.y > height/2.0 {
var min = SpeakDescLabel.width / 2.0
min -= 35
let max = min + 70
if Point.x > min && Point.x < max {
self.TermsOfService()
}
}else{
let min = SpeakDescLabel.width - 80
let max = SpeakDescLabel.width
if Point.x > min && Point.x < max {
self.PrivacyPolicy()
}
}
}
}
......@@ -89,18 +89,42 @@ class SpeakEleLoginViewCtr: SpeakEleBaseViewCtr {
SpeakEamil.placeholder = "E-mail address"
SpeakPs.placeholder = "Password"
}
SpeakDesc.AddTextTap(["Privacy Policy","Terms of Service."])
let privacy = "Privacy Policy".attributed().font(UIFont.montserrat(.medium,size: 10)).underline(.single).paragraphStyle(.center,lineSpacing: 4).build()
let terms = "Terms of Service.".attributed().font(UIFont.montserrat(.medium,size: 10)).underline(.single).paragraphStyle(.center,lineSpacing: 4).build()
let att = "Proceeding further indicates your agreement to our ".attributed().paragraphStyle(.center,lineSpacing: 4).build().combined(with: [privacy," and ", terms])
// SpeakDesc.AddTextTap(["Privacy Policy","Terms of Service."])
let privacy = "Privacy Policy".attributed().font(UIFont.montserrat(.medium,size: 10)).underline(.single).underlineColor().paragraphStyle(.center,lineSpacing: 4).build()
let terms = "Terms of Service.".attributed().font(UIFont.montserrat(.medium,size: 10)).underline(.single).underlineColor().paragraphStyle(.center,lineSpacing: 4).build()
let att = "Proceeding further indicates your agreement to our ".attributed().paragraphStyle(.center,lineSpacing: 4).build().combined(with: [privacy,"\nand ", terms])
SpeakDesc.attributedText = att
SpeakDesc.callblack = { [weak self] text in
guard let v:String = text as? String else { return }
if v == "Privacy Policy" {
self?.PrivacyPolicy()
}else{
self?.TermsOfService()
// SpeakDesc.callblack = { [weak self] text in
// guard let v:String = text as? String else { return }
// if v == "Privacy Policy" {
// self?.PrivacyPolicy()
// }else{
// self?.TermsOfService()
// }
// }
// self.SpeakDesc.lineSpacing(5)
let tap = UITapGestureRecognizer(target: self, action: #selector(tapClick(_:)))
self.SpeakDesc.isUserInteractionEnabled = true
self.SpeakDesc.addGestureRecognizer(tap)
}
@objc private func tapClick(_ res:UIGestureRecognizer) -> Void {
let Point = res.location(in: self.SpeakDesc)
Print(Point)
self.view.layoutIfNeeded()
let height = self.SpeakDesc.height
if Point.y > height/2.0 {
var min = SpeakDesc.width / 2.0
min -= 35
let max = min + 70
if Point.x > min && Point.x < max {
self.TermsOfService()
}
}else{
let min = SpeakDesc.width - 80
let max = SpeakDesc.width
if Point.x > min && Point.x < max {
self.PrivacyPolicy()
}
}
}
......@@ -206,7 +230,7 @@ class SpeakEleLoginViewCtr: SpeakEleBaseViewCtr {
}
break
case .failure(let error):
self.Alert(message: error.localizedDescription)
self.Alert(message: "Login failed")
break
}
}
......@@ -224,7 +248,7 @@ class SpeakEleLoginViewCtr: SpeakEleBaseViewCtr {
}
break
case .failure(let error):
self.Alert(message: error.localizedDescription)
self.Alert(message: "Login failed")
break
}
}
......
......@@ -41,7 +41,7 @@
<rect key="frame" x="0.0" y="174" width="402" height="632"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OiV-6D-z5N">
<rect key="frame" x="0.0" y="0.0" width="402" height="976.33333333333337"/>
<rect key="frame" x="0.0" y="0.0" width="402" height="1016.3333333333334"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="eoM-SK-uFc">
<rect key="frame" x="24" y="0.0" width="354" height="95"/>
......@@ -301,7 +301,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="Duy-h2-44B">
<rect key="frame" x="24" y="734" width="354" height="222.33333333333337"/>
<rect key="frame" x="24" y="734" width="354" height="262.33333333333326"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aRO-jE-Pc0">
<rect key="frame" x="0.0" y="0.0" width="354" height="64"/>
......@@ -335,22 +335,38 @@
<constraint firstItem="4ap-ed-7D7" firstAttribute="leading" secondItem="aRO-jE-Pc0" secondAttribute="leading" id="srg-yj-Oyr"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Proceeding further indicates your agreement to our Privacy Policy and Terms of Service." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZTC-hh-3ze">
<rect key="frame" x="0.0" y="80" width="354" height="24"/>
<fontDescription key="fontDescription" type="system" pointSize="10"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
<integer key="value" value="0"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="fontSize">
<real key="value" value="10"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="31V-h2-xMZ">
<rect key="frame" x="0.0" y="80" width="354" height="64"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ZTC-hh-3ze">
<rect key="frame" x="18.333333333333343" y="0.0" width="317.66666666666663" height="64"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="12" id="tR2-Bc-TiI"/>
</constraints>
<string key="text">Proceeding further indicates your agreement to our Privacy Policy
and Terms of Service.</string>
<fontDescription key="fontDescription" type="system" pointSize="10"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cutomFont">
<integer key="value" value="0"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="number" keyPath="fontSize">
<real key="value" value="10"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</label>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="ZTC-hh-3ze" secondAttribute="bottom" id="LTC-MX-sdP"/>
<constraint firstItem="ZTC-hh-3ze" firstAttribute="top" secondItem="31V-h2-xMZ" secondAttribute="top" id="bTY-Wh-WIN"/>
<constraint firstItem="ZTC-hh-3ze" firstAttribute="centerX" secondItem="31V-h2-xMZ" secondAttribute="centerX" id="blo-8q-lA4"/>
</constraints>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="———————— or ————————" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SQY-CO-4VW">
<rect key="frame" x="0.0" y="119.99999999999999" width="354" height="20.333333333333329"/>
<rect key="frame" x="0.0" y="160" width="354" height="20.333333333333343"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="0.40157312925170069" colorSpace="custom" customColorSpace="sRGB"/>
......@@ -365,7 +381,7 @@
</userDefinedRuntimeAttributes>
</label>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="XDS-Yg-a7Z">
<rect key="frame" x="0.0" y="156.33333333333326" width="354" height="66"/>
<rect key="frame" x="0.0" y="196.33333333333326" width="354" height="66"/>
<subviews>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qex-xZ-2WF">
<rect key="frame" x="0.0" y="0.0" width="169" height="66"/>
......
......@@ -55,6 +55,9 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
AudioPlayerManager.shared.isMute = self.isMute
viewModel.SpeakUpdate = { [weak self] data in
if data is SpeakNetBaseDeflutMode {
self?.SpeakLeassonCollect.isSelected = !(self?.SpeakLeassonCollect.isSelected ?? false)
......@@ -86,6 +89,7 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr {
AudioPlayerManager.shared.setupAudioPlayer(with: Audioplay.first! ,isMuted: self?.isMute ?? false)
Audioplay.remove(at: 0)
AudioPlayerManager.shared.task = Audioplay
AudioPlayerManager.shared.isMute = self?.isMute ?? false
let speed = SpeakElePublicManager.share.PublicData.speed
SpeakAIVideoPlayManager.share.PlaySpeak(duration / speed)
}
......@@ -163,10 +167,10 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr {
viewModel.collect(id: self.dataLesssion?.id ?? 0, isCollect: !sender.isSelected)
}
@IBAction func SoundTapCloseTaps(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
isMute = sender.isSelected
AudioPlayerManager.shared.isMute = self.isMute
AudioPlayerManager.shared.setVolume(sender.isSelected ? 0 : 1)
for (i,_) in self.dataSource.enumerated() {
if let cell = self.SpeakLeassonTableView.cellForRow(at: IndexPath(row: i, section: 0)) as? SpeakDialogAIerCell {
......@@ -270,8 +274,6 @@ class SpeakDialogueViewCtr: SpeakEleBaseViewCtr {
}
}
input.callblack = {[weak self] bt in
if SpeakAudioRecorder.shared.hasPermission {
let call = SpeakEleCallAIViewCtr(viewModel: self?.viewModel)
......
......@@ -13,6 +13,8 @@ class AudioPlayerManager: NSObject, AVAudioPlayerDelegate {
private var audioPlayer: AVAudioPlayer?
static let shared = AudioPlayerManager()
var isMute:Bool = false
private override init() {
}
......@@ -126,7 +128,7 @@ class AudioPlayerManager: NSObject, AVAudioPlayerDelegate {
if flag {
print("音频播放完成")
if self.task.count > 0 {
setupAudioPlayer(with: self.task.first!)
setupAudioPlayer(with: self.task.first! ,isMuted: self.isMute)
self.task.remove(at: 0)
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment